From 6b18efce7fca4c092f56cee1bbc97696dd641091 Mon Sep 17 00:00:00 2001 From: evochriso Date: Sun, 11 Feb 2024 20:55:14 -0500 Subject: [PATCH 01/17] Replace deprecated package Microsoft.Azure.Services.AppAuthentication with Azure.Identity --- src/dbup-sqlserver/AzureSqlConnectionManager.cs | 10 +++++----- src/dbup-sqlserver/dbup-sqlserver.csproj | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dbup-sqlserver/AzureSqlConnectionManager.cs b/src/dbup-sqlserver/AzureSqlConnectionManager.cs index 008cba9..2d5619e 100644 --- a/src/dbup-sqlserver/AzureSqlConnectionManager.cs +++ b/src/dbup-sqlserver/AzureSqlConnectionManager.cs @@ -10,7 +10,8 @@ using DbUp.Support; #if SUPPORTS_AZURE_AD -using Microsoft.Azure.Services.AppAuthentication; +using Azure.Identity; +using Azure.Core; namespace DbUp.SqlServer { @@ -28,12 +29,11 @@ public AzureSqlConnectionManager(string connectionString, string resource) public AzureSqlConnectionManager(string connectionString, string resource, string tenantId, string azureAdInstance = "https://login.microsoftonline.com/") : base(new DelegateConnectionFactory((log, dbManager) => { + var tokenProvider = new DefaultAzureCredential(); + var tokenContext = new TokenRequestContext(scopes: new string[] { resource + "/.default" }, tenantId: tenantId); var conn = new SqlConnection(connectionString) { - AccessToken = new AzureServiceTokenProvider(azureAdInstance: azureAdInstance).GetAccessTokenAsync(resource, tenantId) - .ConfigureAwait(false) - .GetAwaiter() - .GetResult() + AccessToken = tokenProvider.GetToken(tokenContext).Token }; if (dbManager.IsScriptOutputLogged) diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index 8e6c3da..fc19816 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -24,21 +24,21 @@ - + - + - + - - + + From 4b3e9a27e5eabcd29690321ce1a1ae20d0d85afb Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Mon, 18 Mar 2024 17:27:27 +1000 Subject: [PATCH 02/17] Updated DbUp Core +semver: major --- .github/workflows/main.yml | 5 - ...portTests.VerifyBasicSupport.approved.txt} | 6 +- ...JournalCreationIfNameChanged.approved.txt} | 6 +- ....VerifyVariableSubstitutions.approved.txt} | 6 +- .../NoPublicApiChanges.Run.Net.verified.cs | 86 ------------ ....cs => NoPublicApiChanges.Run.approved.cs} | 2 +- src/Tests/SqlScriptExecutorTests.cs | 130 ++++++++++-------- src/Tests/Tests.csproj | 6 +- .../AzureSqlConnectionManager.cs | 72 +++++----- .../AzureSqlServerExtensions.cs | 4 - .../Helpers/TemporarySqlDatabase.cs | 4 - src/dbup-sqlserver/SqlConnectionManager.cs | 6 +- src/dbup-sqlserver/SqlContextUpgradeLog.cs | 24 ---- src/dbup-sqlserver/SqlScriptExecutor.cs | 10 +- src/dbup-sqlserver/SqlServerExtensions.cs | 28 +--- src/dbup-sqlserver/dbup-sqlserver.csproj | 40 ++---- 16 files changed, 130 insertions(+), 305 deletions(-) rename src/Tests/ApprovalFiles/{DatabaseSupportTests.VerifyBasicSupport.verified.txt => DatabaseSupportTests.VerifyBasicSupport.approved.txt} (90%) rename src/Tests/ApprovalFiles/{DatabaseSupportTests.VerifyJournalCreationIfNameChanged.verified.txt => DatabaseSupportTests.VerifyJournalCreationIfNameChanged.approved.txt} (91%) rename src/Tests/ApprovalFiles/{DatabaseSupportTests.VerifyVariableSubstitutions.verified.txt => DatabaseSupportTests.VerifyVariableSubstitutions.approved.txt} (90%) delete mode 100644 src/Tests/ApprovalFiles/NoPublicApiChanges.Run.Net.verified.cs rename src/Tests/ApprovalFiles/{NoPublicApiChanges.Run.DotNet.verified.cs => NoPublicApiChanges.Run.approved.cs} (99%) delete mode 100644 src/dbup-sqlserver/SqlContextUpgradeLog.cs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f1a6bc8..eed5b00 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,11 +18,6 @@ jobs: with: fetch-depth: 0 # all - - name: Setup .NET 2.0 # Remove in v5.0 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 2.0.x - - name: Setup .NET 8.0 uses: actions/setup-dotnet@v1 with: diff --git a/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyBasicSupport.verified.txt b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyBasicSupport.approved.txt similarity index 90% rename from src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyBasicSupport.verified.txt rename to src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyBasicSupport.approved.txt index 6192175..4df7abb 100644 --- a/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyBasicSupport.verified.txt +++ b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyBasicSupport.approved.txt @@ -1,11 +1,11 @@ -DB Operation: Open connection +DB Operation: Open connection Info: Beginning database upgrade -Info: Checking whether journal table exists.. +Info: Checking whether journal table exists DB Operation: Execute scalar command: select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'SchemaVersions' DB Operation: Dispose command Info: Journal table does not exist Info: Executing Database Server script 'Script0001.sql' -Info: Checking whether journal table exists.. +Info: Checking whether journal table exists DB Operation: Execute scalar command: select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'SchemaVersions' DB Operation: Dispose command Info: Creating the [SchemaVersions] table diff --git a/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyJournalCreationIfNameChanged.verified.txt b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyJournalCreationIfNameChanged.approved.txt similarity index 91% rename from src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyJournalCreationIfNameChanged.verified.txt rename to src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyJournalCreationIfNameChanged.approved.txt index 9ca0e23..1f52d9c 100644 --- a/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyJournalCreationIfNameChanged.verified.txt +++ b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyJournalCreationIfNameChanged.approved.txt @@ -1,11 +1,11 @@ -DB Operation: Open connection +DB Operation: Open connection Info: Beginning database upgrade -Info: Checking whether journal table exists.. +Info: Checking whether journal table exists DB Operation: Execute scalar command: select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'TestSchemaVersions' and TABLE_SCHEMA = 'test' DB Operation: Dispose command Info: Journal table does not exist Info: Executing Database Server script 'Script0001.sql' -Info: Checking whether journal table exists.. +Info: Checking whether journal table exists DB Operation: Execute scalar command: select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'TestSchemaVersions' and TABLE_SCHEMA = 'test' DB Operation: Dispose command Info: Creating the [test].[TestSchemaVersions] table diff --git a/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyVariableSubstitutions.verified.txt b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyVariableSubstitutions.approved.txt similarity index 90% rename from src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyVariableSubstitutions.verified.txt rename to src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyVariableSubstitutions.approved.txt index 9c20bfc..c3fa619 100644 --- a/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyVariableSubstitutions.verified.txt +++ b/src/Tests/ApprovalFiles/DatabaseSupportTests.VerifyVariableSubstitutions.approved.txt @@ -1,11 +1,11 @@ -DB Operation: Open connection +DB Operation: Open connection Info: Beginning database upgrade -Info: Checking whether journal table exists.. +Info: Checking whether journal table exists DB Operation: Execute scalar command: select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'SchemaVersions' DB Operation: Dispose command Info: Journal table does not exist Info: Executing Database Server script 'Script0001.sql' -Info: Checking whether journal table exists.. +Info: Checking whether journal table exists DB Operation: Execute scalar command: select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'SchemaVersions' DB Operation: Dispose command Info: Creating the [SchemaVersions] table diff --git a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.Net.verified.cs b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.Net.verified.cs deleted file mode 100644 index 288c72f..0000000 --- a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.Net.verified.cs +++ /dev/null @@ -1,86 +0,0 @@ -[assembly: System.CLSCompliantAttribute(true)] -[assembly: System.Runtime.InteropServices.ComVisibleAttribute(false)] -[assembly: System.Runtime.InteropServices.GuidAttribute("8190b40b-ac5b-414f-8a00-9b6a2c12b010")] - -public static class AzureSqlServerExtensions -{ - public static DbUp.Builder.UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema) { } - public static DbUp.Builder.UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, string resource) { } - public static DbUp.Builder.UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, string resource, string tenantId, string azureAdInstance = "https://login.microsoftonline.com/") { } -} -public static class SqlServerExtensions -{ - public static DbUp.Builder.UpgradeEngineBuilder JournalToSqlTable(this DbUp.Builder.UpgradeEngineBuilder builder, string schema, string table) { } - public static DbUp.Builder.UpgradeEngineBuilder LogToSqlContext(this DbUp.Builder.UpgradeEngineBuilder builder) { } - public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString) { } - public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema) { } - public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, DbUp.Engine.Transactions.IConnectionManager connectionManager, string schema = null) { } - [System.ObsoleteAttribute("Use "AzureSqlDatabaseWithIntegratedSecurity(this SupportedDatabases, string, string)" if passing "true" to "useAzureSqlIntegratedSecurity".")] - public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, bool useAzureSqlIntegratedSecurity) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForDropDatabase supported, string connectionString) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, string collation) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForDropDatabase supported, string connectionString, int commandTimeout) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, string collation) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition, string collation) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForDropDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger, int timeout = -1) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition, string collation) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger, int timeout = -1, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition = 0, string collation = null) { } -} -namespace DbUp.SqlServer -{ - public enum AzureDatabaseEdition : int - { - None = 0 - Basic = 1 - Standard = 2 - Premium = 3 - } - public class AzureSqlConnectionManager : DbUp.Engine.Transactions.DatabaseConnectionManager, DbUp.Engine.Transactions.IConnectionManager - { - public AzureSqlConnectionManager(string connectionString) { } - public AzureSqlConnectionManager(string connectionString, string resource) { } - public AzureSqlConnectionManager(string connectionString, string resource, string tenantId, string azureAdInstance = "https://login.microsoftonline.com/") { } - public override System.Collections.Generic.IEnumerable SplitScriptIntoCommands(string scriptContents) { } - } - public class SqlConnectionManager : DbUp.Engine.Transactions.DatabaseConnectionManager, DbUp.Engine.Transactions.IConnectionManager - { - public SqlConnectionManager(string connectionString) { } - public override System.Collections.Generic.IEnumerable SplitScriptIntoCommands(string scriptContents) { } - } - public class SqlScriptExecutor : DbUp.Support.ScriptExecutor, DbUp.Engine.IScriptExecutor - { - public SqlScriptExecutor(System.Func connectionManagerFactory, System.Func log, string schema, System.Func variablesEnabled, System.Collections.Generic.IEnumerable scriptPreprocessors, System.Func journalFactory) { } - protected override void ExecuteCommandsWithinExceptionHandler(int index, DbUp.Engine.SqlScript script, System.Action executeCommand) { } - protected override string GetVerifySchemaSql(string schema) { } - } - public class SqlServerObjectParser : DbUp.Support.SqlObjectParser, DbUp.Engine.ISqlObjectParser - { - public SqlServerObjectParser() { } - public override string QuoteIdentifier(string objectName, DbUp.Support.ObjectNameOptions objectNameOptions) { } - } - public class SqlTableJournal : DbUp.Support.TableJournal, DbUp.Engine.IJournal - { - public SqlTableJournal(System.Func connectionManager, System.Func logger, string schema, string table) { } - protected override string CreateSchemaTableSql(string quotedPrimaryKeyName) { } - protected override string GetInsertJournalEntrySql(string scriptName, string applied) { } - protected override string GetJournalEntriesSql() { } - } -} -namespace DbUp.SqlServer.Helpers -{ - public class TemporarySqlDatabase : System.IDisposable - { - public TemporarySqlDatabase(string name) { } - public TemporarySqlDatabase(System.Data.SqlClient.SqlConnectionStringBuilder connectionStringBuilder) { } - public TemporarySqlDatabase(string name, string instanceName) { } - public DbUp.Helpers.AdHocSqlRunner AdHoc { get; } - public string ConnectionString { get; } - public void Create() { } - public void Dispose() { } - public static DbUp.SqlServer.Helpers.TemporarySqlDatabase FromConnectionString(string connectionString) { } - } -} diff --git a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.DotNet.verified.cs b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs similarity index 99% rename from src/Tests/ApprovalFiles/NoPublicApiChanges.Run.DotNet.verified.cs rename to src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs index 98376b6..57a0780 100644 --- a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.DotNet.verified.cs +++ b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs @@ -1,4 +1,4 @@ -[assembly: System.CLSCompliantAttribute(true)] +[assembly: System.CLSCompliantAttribute(true)] [assembly: System.Runtime.InteropServices.ComVisibleAttribute(false)] [assembly: System.Runtime.InteropServices.GuidAttribute("8190b40b-ac5b-414f-8a00-9b6a2c12b010")] diff --git a/src/Tests/SqlScriptExecutorTests.cs b/src/Tests/SqlScriptExecutorTests.cs index 9107103..21908e6 100644 --- a/src/Tests/SqlScriptExecutorTests.cs +++ b/src/Tests/SqlScriptExecutorTests.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Data; +using System.Data; using System.Data.Common; using DbUp.Engine; using DbUp.Engine.Output; @@ -18,7 +16,8 @@ public class SqlScriptExecutorTests [Fact] public void verify_schema_should_not_check_when_schema_is_null() { - var executor = new SqlScriptExecutor(() => Substitute.For(), () => null, null, () => false, null, () => Substitute.For()); + var executor = new SqlScriptExecutor(() => Substitute.For(), () => null, null, + () => false, null, () => Substitute.For()); executor.VerifySchema(); } @@ -26,10 +25,8 @@ public void verify_schema_should_not_check_when_schema_is_null() [Fact] public void when_schema_is_null_schema_is_stripped_from_scripts() { - var dbConnection = Substitute.For(); var command = Substitute.For(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => new ConsoleUpgradeLog(), null, () => true, null, () => Substitute.For()); + var executor = GetSqlScriptExecutor(command); executor.Execute(new SqlScript("Test", "create $schema$.Table")); @@ -40,12 +37,11 @@ public void when_schema_is_null_schema_is_stripped_from_scripts() [Fact] public void uses_variable_substitute_preprocessor_when_running_scripts() { - var dbConnection = Substitute.For(); var command = Substitute.For(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => new ConsoleUpgradeLog(), null, () => true, null, () => Substitute.For()); + var executor = GetSqlScriptExecutor(command); - executor.Execute(new SqlScript("Test", "create $foo$.Table"), new Dictionary { { "foo", "bar" } }); + executor.Execute(new SqlScript("Test", "create $foo$.Table"), + new Dictionary { { "foo", "bar" } }); command.Received().ExecuteNonQuery(); command.CommandText.ShouldBe("create bar.Table"); @@ -58,12 +54,11 @@ public void uses_variable_subtitute_preprocessor_when_running_scripts_with_singl create $foo$.Table"; var oneLineCommentResult = @"--from excel $A$6 create bar.Table"; - var dbConnection = Substitute.For(); - var command = Substitute.For(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => new ConsoleUpgradeLog(), null, () => true, null, () => Substitute.For()); - executor.Execute(new SqlScript("Test", oneLineComment), new Dictionary { { "foo", "bar" } }); + var command = Substitute.For(); + var executor = GetSqlScriptExecutor(command); + executor.Execute(new SqlScript("Test", oneLineComment), + new Dictionary { { "foo", "bar" } }); command.Received().ExecuteNonQuery(); command.CommandText.ShouldBe(oneLineCommentResult); @@ -76,12 +71,14 @@ public void uses_variable_substitute_preprocessor_when_running_scripts_with_one_ create $foo$.Table"; var oneLineCommentResult = @"/* from excel $A$6 */ create bar.Table"; - var dbConnection = Substitute.For(); + var command = Substitute.For(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => new ConsoleUpgradeLog(), null, () => true, null, () => Substitute.For()); + var executor = GetSqlScriptExecutor(command); + executor.Execute(new SqlScript("Test", oneLineComment), + new Dictionary { { "foo", "bar" } }); - executor.Execute(new SqlScript("Test", oneLineComment), new Dictionary { { "foo", "bar" } }); + executor.Execute(new SqlScript("Test", oneLineComment), + new Dictionary { { "foo", "bar" } }); command.Received().ExecuteNonQuery(); command.CommandText.ShouldBe(oneLineCommentResult); @@ -101,12 +98,13 @@ some comment from excel $A$6 some comment */ - create bar.Table"; var dbConnection = Substitute.For(); + create bar.Table"; + var dbConnection = Substitute.For(); var command = Substitute.For(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => new ConsoleUpgradeLog(), null, () => true, null, () => Substitute.For()); + var executor = GetSqlScriptExecutor(command); - executor.Execute(new SqlScript("Test", multiLineComment), new Dictionary { { "foo", "bar" } }); + executor.Execute(new SqlScript("Test", multiLineComment), + new Dictionary { { "foo", "bar" } }); command.Received().ExecuteNonQuery(); command.CommandText.ShouldBe(multiLineCommentResult); @@ -126,12 +124,13 @@ some comment --from excel $A$6 some comment */ - create bar.Table"; var dbConnection = Substitute.For(); + create bar.Table"; + var dbConnection = Substitute.For(); var command = Substitute.For(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => new ConsoleUpgradeLog(), null, () => true, null, () => Substitute.For()); + var executor = GetSqlScriptExecutor(command); - executor.Execute(new SqlScript("Test", multiLineComment), new Dictionary { { "foo", "bar" } }); + executor.Execute(new SqlScript("Test", multiLineComment), + new Dictionary { { "foo", "bar" } }); command.Received().ExecuteNonQuery(); command.CommandText.ShouldBe(multiLineCommentResult); @@ -151,12 +150,13 @@ some comment /* from excel $A$6 */ some comment */ - create bar.Table"; var dbConnection = Substitute.For(); + create bar.Table"; + var dbConnection = Substitute.For(); var command = Substitute.For(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => new ConsoleUpgradeLog(), null, () => true, null, () => Substitute.For()); + var executor = GetSqlScriptExecutor(command); - executor.Execute(new SqlScript("Test", multiLineComment), new Dictionary { { "foo", "bar" } }); + executor.Execute(new SqlScript("Test", multiLineComment), + new Dictionary { { "foo", "bar" } }); command.Received().ExecuteNonQuery(); command.CommandText.ShouldBe(multiLineCommentResult); @@ -165,24 +165,22 @@ some comment [Fact] public void does_not_use_variable_substitute_preprocessor_when_setting_false() { - var dbConnection = Substitute.For(); var command = Substitute.For(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => new ConsoleUpgradeLog(), null, () => false, null, () => Substitute.For()); + var executor = GetSqlScriptExecutor(command, variablesEnabled: false); - executor.Execute(new SqlScript("Test", "create $foo$.Table"), new Dictionary { { "foo", "bar" } }); + executor.Execute(new SqlScript("Test", "create $foo$.Table"), + new Dictionary { { "foo", "bar" } }); command.Received().ExecuteNonQuery(); command.CommandText.ShouldBe("create $foo$.Table"); } + [Fact] public void uses_variable_subtitutes_schema() { - var dbConnection = Substitute.For(); var command = Substitute.For(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => new ConsoleUpgradeLog(), "foo", () => true, null, () => Substitute.For()); + var executor = GetSqlScriptExecutor(command, schema: "foo"); executor.Execute(new SqlScript("Test", "create $schema$.Table")); @@ -193,7 +191,6 @@ public void uses_variable_subtitutes_schema() [Fact] public void logs_output_when_configured_to() { - var dbConnection = Substitute.For(); var command = Substitute.For(); var reader = Substitute.For(); @@ -210,31 +207,22 @@ public void logs_output_when_configured_to() command.ExecuteReader().Returns(reader); var logger = new CaptureLogsLogger(); - dbConnection.CreateCommand().Returns(command); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true) { IsScriptOutputLogged = true }, - () => logger, - "foo", - () => true, - null, - () => Substitute.For()); + var executor = GetSqlScriptExecutor(command, log: logger, schema: "foo", isScriptOutputLogged: true); executor.Execute(new SqlScript("Test", "SELECT * FROM $schema$.[Table]")); - command.Received().ExecuteReader(); + command.ReceivedWithAnyArgs().ExecuteReader(); command.DidNotReceive().ExecuteNonQuery(); command.CommandText.ShouldBe("SELECT * FROM [foo].[Table]"); logger.Log.Trim() - .ShouldBe(string.Join(Environment.NewLine, new[] - { - "Info: Executing Database Server script 'Test'", - "Info: -------------", - "Info: | One | Two |", - "Info: -------------", - "Info: | A | B |", - "Info: -------------", - "Info:" - })); + .ShouldBe(string.Join(Environment.NewLine, + new[] + { + "Info: Executing Database Server script 'Test'", "Info: -------------", + "Info: | One | Two |", "Info: -------------", "Info: | A | B |", + "Info: -------------", "Info:" + })); } [Fact] @@ -250,14 +238,34 @@ public void logs_when_dbexception() }); dbConnection.CreateCommand().Returns(command); var logger = Substitute.For(); - logger.WhenForAnyArgs(x => x.WriteError(null, null)).Do(x => Console.WriteLine(x.Arg(), x.Arg())); + logger.WhenForAnyArgs(x => x.LogError(null, (object[]?)null)) + .Do(x => Console.WriteLine(x.Arg(), x.Arg())); - var executor = new SqlScriptExecutor(() => new TestConnectionManager(dbConnection, true), () => logger, null, () => true, null, () => Substitute.For()); + var executor = GetSqlScriptExecutor(command, log: logger); Action exec = () => executor.Execute(new SqlScript("Test", "create $schema$.Table")); exec.ShouldThrow(); command.Received().ExecuteNonQuery(); - logger.ReceivedWithAnyArgs().WriteError("", null); + logger.ReceivedWithAnyArgs().LogError("", null); + } + + static SqlScriptExecutor GetSqlScriptExecutor( + IDbCommand command, + bool variablesEnabled = true, + string? schema = null, + IUpgradeLog? log = null, + bool isScriptOutputLogged = false + ) + { + var dbConnection = Substitute.For(); + dbConnection.CreateCommand().Returns(command); + var testConnectionManager = new TestConnectionManager(dbConnection) { IsScriptOutputLogged = isScriptOutputLogged }; + log ??= new ConsoleUpgradeLog(); + testConnectionManager.OperationStarting(log, []); + + var executor = new SqlScriptExecutor(() => testConnectionManager, () => log, schema, () => variablesEnabled, + null, () => Substitute.For()); + return executor; } } } diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 13d4abc..8a9230b 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -1,16 +1,16 @@ - net462;net8 + net8 Tests DbUp.SqlServer.Tests - + enable enable - + diff --git a/src/dbup-sqlserver/AzureSqlConnectionManager.cs b/src/dbup-sqlserver/AzureSqlConnectionManager.cs index 008cba9..8074efe 100644 --- a/src/dbup-sqlserver/AzureSqlConnectionManager.cs +++ b/src/dbup-sqlserver/AzureSqlConnectionManager.cs @@ -1,54 +1,46 @@ using System.Collections.Generic; -#if SUPPORTS_MICROSOFT_SQL_CLIENT using Microsoft.Data.SqlClient; -#else -using System.Data.SqlClient; -#endif - using DbUp.Engine.Transactions; using DbUp.Support; -#if SUPPORTS_AZURE_AD using Microsoft.Azure.Services.AppAuthentication; -namespace DbUp.SqlServer +namespace DbUp.SqlServer; + +/// Manages an Azure Sql Server database connection. +public class AzureSqlConnectionManager : DatabaseConnectionManager { - /// Manages an Azure Sql Server database connection. - public class AzureSqlConnectionManager : DatabaseConnectionManager - { - public AzureSqlConnectionManager(string connectionString) - : this(connectionString, "https://database.windows.net/", null) - { } + public AzureSqlConnectionManager(string connectionString) + : this(connectionString, "https://database.windows.net/", null) + { } - public AzureSqlConnectionManager(string connectionString, string resource) - : this(connectionString, resource, null) - { } + public AzureSqlConnectionManager(string connectionString, string resource) + : this(connectionString, resource, null) + { } - public AzureSqlConnectionManager(string connectionString, string resource, string tenantId, string azureAdInstance = "https://login.microsoftonline.com/") - : base(new DelegateConnectionFactory((log, dbManager) => - { - var conn = new SqlConnection(connectionString) - { - AccessToken = new AzureServiceTokenProvider(azureAdInstance: azureAdInstance).GetAccessTokenAsync(resource, tenantId) - .ConfigureAwait(false) - .GetAwaiter() - .GetResult() - }; - - if (dbManager.IsScriptOutputLogged) - conn.InfoMessage += (sender, e) => log.WriteInformation($"{{0}}", e.Message); - - return conn; - })) - { } - - public override IEnumerable SplitScriptIntoCommands(string scriptContents) + public AzureSqlConnectionManager(string connectionString, string resource, string tenantId, string azureAdInstance = "https://login.microsoftonline.com/") + : base(new DelegateConnectionFactory((log, dbManager) => { - var commandSplitter = new SqlCommandSplitter(); - var scriptStatements = commandSplitter.SplitScriptIntoCommands(scriptContents); - return scriptStatements; - } + var conn = new SqlConnection(connectionString) + { + AccessToken = new AzureServiceTokenProvider(azureAdInstance: azureAdInstance).GetAccessTokenAsync(resource, tenantId) + .ConfigureAwait(false) + .GetAwaiter() + .GetResult() + }; + + if (dbManager.IsScriptOutputLogged) + conn.InfoMessage += (sender, e) => log.LogInformation($"{{0}}", e.Message); + + return conn; + })) + { } + + public override IEnumerable SplitScriptIntoCommands(string scriptContents) + { + var commandSplitter = new SqlCommandSplitter(); + var scriptStatements = commandSplitter.SplitScriptIntoCommands(scriptContents); + return scriptStatements; } } -#endif diff --git a/src/dbup-sqlserver/AzureSqlServerExtensions.cs b/src/dbup-sqlserver/AzureSqlServerExtensions.cs index 8477180..de7aa57 100644 --- a/src/dbup-sqlserver/AzureSqlServerExtensions.cs +++ b/src/dbup-sqlserver/AzureSqlServerExtensions.cs @@ -2,8 +2,6 @@ using DbUp.Builder; using DbUp.SqlServer; -#if SUPPORTS_AZURE_AD - /// Configuration extension methods for Azure SQL Server. // NOTE: DO NOT MOVE THIS TO A NAMESPACE // Since the class just contains extension methods, we leave it in the global:: namespace so that it is always available @@ -45,5 +43,3 @@ public static UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this S } } #pragma warning restore CA1050 // Declare types in namespaces - -#endif diff --git a/src/dbup-sqlserver/Helpers/TemporarySqlDatabase.cs b/src/dbup-sqlserver/Helpers/TemporarySqlDatabase.cs index c53fd0c..8a84c2c 100644 --- a/src/dbup-sqlserver/Helpers/TemporarySqlDatabase.cs +++ b/src/dbup-sqlserver/Helpers/TemporarySqlDatabase.cs @@ -1,9 +1,5 @@ using System; -#if SUPPORTS_MICROSOFT_SQL_CLIENT using Microsoft.Data.SqlClient; -#else -using System.Data.SqlClient; -#endif using DbUp.Helpers; diff --git a/src/dbup-sqlserver/SqlConnectionManager.cs b/src/dbup-sqlserver/SqlConnectionManager.cs index 16f0500..d2dc6cf 100644 --- a/src/dbup-sqlserver/SqlConnectionManager.cs +++ b/src/dbup-sqlserver/SqlConnectionManager.cs @@ -1,9 +1,5 @@ using System.Collections.Generic; -#if SUPPORTS_MICROSOFT_SQL_CLIENT using Microsoft.Data.SqlClient; -#else -using System.Data.SqlClient; -#endif using DbUp.Engine.Transactions; using DbUp.Support; @@ -24,7 +20,7 @@ public SqlConnectionManager(string connectionString) var conn = new SqlConnection(connectionString); if (dbManager.IsScriptOutputLogged) - conn.InfoMessage += (sender, e) => log.WriteInformation($"{{0}}", e.Message); + conn.InfoMessage += (sender, e) => log.LogInformation($"{{0}}", e.Message); return conn; })) diff --git a/src/dbup-sqlserver/SqlContextUpgradeLog.cs b/src/dbup-sqlserver/SqlContextUpgradeLog.cs deleted file mode 100644 index 03419ba..0000000 --- a/src/dbup-sqlserver/SqlContextUpgradeLog.cs +++ /dev/null @@ -1,24 +0,0 @@ -#if SUPPORTS_SQL_CONTEXT -using Microsoft.SqlServer.Server; - -namespace DbUp.Engine.Output -{ - class SqlContextUpgradeLog : IUpgradeLog - { - public void WriteInformation(string format, params object[] args) - { - SqlContext.Pipe.Send("INFO: " + string.Format(format, args)); - } - - public void WriteError(string format, params object[] args) - { - SqlContext.Pipe.Send("ERROR: " + string.Format(format, args)); - } - - public void WriteWarning(string format, params object[] args) - { - SqlContext.Pipe.Send("WARN: " + string.Format(format, args)); - } - } -} -#endif \ No newline at end of file diff --git a/src/dbup-sqlserver/SqlScriptExecutor.cs b/src/dbup-sqlserver/SqlScriptExecutor.cs index df6653f..2e5a45c 100644 --- a/src/dbup-sqlserver/SqlScriptExecutor.cs +++ b/src/dbup-sqlserver/SqlScriptExecutor.cs @@ -1,10 +1,6 @@ using System; using System.Collections.Generic; -#if SUPPORTS_MICROSOFT_SQL_CLIENT using Microsoft.Data.SqlClient; -#else -using System.Data.SqlClient; -#endif using DbUp.Engine; using DbUp.Engine.Output; using DbUp.Engine.Transactions; @@ -45,9 +41,9 @@ protected override void ExecuteCommandsWithinExceptionHandler(int index, SqlScri } catch (SqlException sqlException) { - Log().WriteInformation("SQL exception has occurred in script: '{0}'", script.Name); - Log().WriteError("Script block number: {0}; Block line {1}; Procedure {2}; Number {3}; Message: {4}", index, sqlException.LineNumber, sqlException.Procedure, sqlException.Number, sqlException.Message); - Log().WriteError(sqlException.ToString()); + Log().LogInformation("SQL exception has occurred in script: '{0}'", script.Name); + Log().LogError("Script block number: {0}; Block line {1}; Procedure {2}; Number {3}; Message: {4}", index, sqlException.LineNumber, sqlException.Procedure, sqlException.Number, sqlException.Message); + Log().LogError(sqlException.ToString()); throw; } } diff --git a/src/dbup-sqlserver/SqlServerExtensions.cs b/src/dbup-sqlserver/SqlServerExtensions.cs index 48ca23e..a1b0d44 100644 --- a/src/dbup-sqlserver/SqlServerExtensions.cs +++ b/src/dbup-sqlserver/SqlServerExtensions.cs @@ -1,10 +1,6 @@ using System; using System.Data; -#if SUPPORTS_MICROSOFT_SQL_CLIENT using Microsoft.Data.SqlClient; -#else -using System.Data.SqlClient; -#endif using DbUp; using DbUp.Builder; using DbUp.Engine.Output; @@ -48,7 +44,6 @@ public static UpgradeEngineBuilder SqlDatabase(this SupportedDatabases supported return SqlDatabase(new SqlConnectionManager(connectionString), schema); } -#if SUPPORTS_AZURE_AD /// Creates an upgrader for SQL Server databases. /// Fluent helper type. /// The connection string. @@ -65,7 +60,6 @@ public static UpgradeEngineBuilder SqlDatabase(this SupportedDatabases supported return supported.SqlDatabase(new SqlConnectionManager(connectionString), schema); } -#endif /// /// Creates an upgrader for SQL Server databases. @@ -111,20 +105,6 @@ public static UpgradeEngineBuilder JournalToSqlTable(this UpgradeEngineBuilder b return builder; } -#if SUPPORTS_SQL_CONTEXT - /// - /// Logs to SqlContext.Pipe, for use with "context connection=true". - /// - /// The builder. - /// - /// The same builder - /// - public static UpgradeEngineBuilder LogToSqlContext(this UpgradeEngineBuilder builder) - { - return builder.LogTo(new SqlContextUpgradeLog()); - } -#endif - /// /// Ensures that the database specified in the connection string exists. /// @@ -296,7 +276,7 @@ public static void SqlDatabase( command.ExecuteNonQuery(); } - logger.WriteInformation(@"Created database {0}", databaseName); + logger.LogInformation(@"Created database {0}", databaseName); } } @@ -312,7 +292,7 @@ static bool DatabaseExistsIfConnectedToDirectly(IUpgradeLog logger, string conne } catch { - logger.WriteInformation("Could not connect to the database directly"); + logger.LogInformation("Could not connect to the database directly"); return false; } } @@ -364,7 +344,7 @@ public static void SqlDatabase(this SupportedDatabasesForDropDatabase supported, command.ExecuteNonQuery(); } - logger.WriteInformation("Dropped database {0}", databaseName); + logger.LogInformation("Dropped database {0}", databaseName); } } @@ -388,7 +368,7 @@ static void GetMasterConnectionStringBuilder(string connectionString, IUpgradeLo Password = "******" }; - logger.WriteInformation("Master ConnectionString => {0}", logMasterConnectionStringBuilder.ConnectionString); + logger.LogInformation("Master ConnectionString => {0}", logMasterConnectionStringBuilder.ConnectionString); masterConnectionString = masterConnectionStringBuilder.ConnectionString; } diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index 8e6c3da..631fa94 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -6,7 +6,7 @@ DbUp Contributors DbUp Copyright © DbUp Contributors 2015 - netstandard1.3;netstandard2.0;net462;net6.0 + netstandard2.0 dbup-sqlserver DbUp.SqlServer dbup-sqlserver @@ -16,43 +16,19 @@ dbup-icon.png + + true + true + embedded + + - + - - - - - - - - - - - - - - - - - - - - $(DefineConstants);SUPPORTS_SQL_CONTEXT;SUPPORTS_AZURE_AD - - - - $(DefineConstants);SUPPORTS_AZURE_AD - - - - $(DefineConstants);SUPPORTS_MICROSOFT_SQL_CLIENT - - From 45c0b574768a2bb76d9c12555a9492f58273df0d Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Mon, 18 Mar 2024 17:31:47 +1000 Subject: [PATCH 03/17] Update all the references --- src/Tests/Tests.csproj | 6 +++--- src/dbup-sqlserver/dbup-sqlserver.csproj | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 8a9230b..3fbd78d 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -11,9 +11,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index 631fa94..c50ba89 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -25,7 +25,7 @@ - + From 909c41f4d466ba2db5cbd3c6a0fa442df11adbd3 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Mon, 18 Mar 2024 17:33:44 +1000 Subject: [PATCH 04/17] Removed old build props --- src/Directory.Build.props | 13 ------------- src/dbup-sqlserver.sln | 1 + 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 196f572..71548cd 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -11,17 +11,4 @@ true - - - - true - - - true - - - embedded - - - diff --git a/src/dbup-sqlserver.sln b/src/dbup-sqlserver.sln index db152d8..e0eb44c 100644 --- a/src/dbup-sqlserver.sln +++ b/src/dbup-sqlserver.sln @@ -23,6 +23,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{77157734-01D ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig dbup-sqlserver.sln.DotSettings = dbup-sqlserver.sln.DotSettings + Directory.Build.props = Directory.Build.props EndProjectSection EndProject Global From 37434ec7a33a8946f2a181b055a895ef418b1c22 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Sat, 20 Jul 2024 10:27:35 +1000 Subject: [PATCH 05/17] Update SqlClient and some test package references --- src/Tests/Tests.csproj | 6 +++--- src/dbup-sqlserver.sln.DotSettings | 3 +++ src/dbup-sqlserver/dbup-sqlserver.csproj | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 3fbd78d..e986f0f 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -11,9 +11,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/dbup-sqlserver.sln.DotSettings b/src/dbup-sqlserver.sln.DotSettings index 2c78c0a..d3334fb 100644 --- a/src/dbup-sqlserver.sln.DotSettings +++ b/src/dbup-sqlserver.sln.DotSettings @@ -5,5 +5,8 @@ SQ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + True <data><IncludeFilters /><ExcludeFilters /></data> <data /> \ No newline at end of file diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index c50ba89..4eeb19f 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -25,7 +25,7 @@ - + From ef794591b70359e1a455e1c85ca8d1e5ca4d2a88 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Sat, 20 Jul 2024 10:40:21 +1000 Subject: [PATCH 06/17] Used re-usable workflows --- .github/workflows/main.yml | 80 ++------------------------- .github/workflows/publish-release.yml | 12 ++++ .github/workflows/test-report.yml | 12 ++++ 3 files changed, 28 insertions(+), 76 deletions(-) create mode 100644 .github/workflows/publish-release.yml create mode 100644 .github/workflows/test-report.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f1a6bc8..26798d9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,84 +2,12 @@ name: CI on: push: + branches: + - '**' # Ignores pushes of tags pull_request: workflow_dispatch: jobs: build: - runs-on: windows-latest # Use Ubuntu in v5.0 - - env: - DOTNET_NOLOGO: true - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true # Avoid pre-populating the NuGet package cache - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # all - - - name: Setup .NET 2.0 # Remove in v5.0 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 2.0.x - - - name: Setup .NET 8.0 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 8.0.x - - - name: Install NuGet - uses: NuGet/setup-nuget@v1.2.0 - - - name: Install GitVersion - uses: gittools/actions/gitversion/setup@v0 - with: - versionSpec: '5.x' - - - name: Run GitVersion - id: gitversion - uses: gittools/actions/gitversion/execute@v0 - - - name: Display SemVer - run: | - echo "SemVer: $env:GitVersion_SemVer" - - - name: Add DbUp NuGet Source - run: dotnet nuget add source --name DbUp --username DbUp --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text https://nuget.pkg.github.com/DbUp/index.json - - - name: Restore - run: dotnet restore - working-directory: src - - - name: Build - run: dotnet build -c Release --no-restore /p:Version=$env:GitVersion_SemVer - working-directory: src - - - name: Test - run: dotnet test --no-build -c Release --logger trx --logger "console;verbosity=detailed" --results-directory ../artifacts - working-directory: src - - - name: Pack - run: dotnet pack --no-build -c Release -o ../artifacts /p:Version=$env:GitVersion_SemVer - working-directory: src - - - name: Pack placeholder dbup package - run: nuget pack ./dbup/dbup.nuspec -OutputDirectory ../artifacts -Version $env:GitVersion_SemVer - working-directory: src - - - name: Push NuGet packages to GitHub Packages ⬆️ - working-directory: artifacts - run: dotnet nuget push *.nupkg --api-key ${{ secrets.GITHUB_TOKEN }} --source "https://nuget.pkg.github.com/DbUp/index.json" - - - name: Push NuGet packages to NuGet ⬆️ - if: ${{ steps.gitversion.outputs.preReleaseLabel == '' }} - working-directory: artifacts - run: dotnet nuget push *.nupkg --api-key ${{ secrets.NUGET_APIKEY }} --source https://api.nuget.org/v3/index.json - - - name: Test Report 🧪 - uses: dorny/test-reporter@v1 - if: ${{ always() }} - with: - name: Tests - path: artifacts/*.trx - reporter: dotnet-trx + name: Build + uses: DbUp/Universe/.github/workflows/build.yml@main diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 0000000..eb5e03f --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,12 @@ +name: Publish DbUp Packages to NuGet + +on: + release: + types: [ published ] + workflow_dispatch: + +jobs: + publish: + name: Publish Package + uses: DbUp/Universe/.github/workflows/publish-release.yml@main + secrets: inherit diff --git a/.github/workflows/test-report.yml b/.github/workflows/test-report.yml new file mode 100644 index 0000000..33fdc60 --- /dev/null +++ b/.github/workflows/test-report.yml @@ -0,0 +1,12 @@ +name: Test Report +run-name: Generate Test Report for workflow ${{ github.event.workflow_run.name }} run ${{ github.event.workflow_run.run_number }} branch ${{ github.event.workflow_run.head_branch }} + +on: + workflow_run: + workflows: ["CI", "build"] + types: [completed] + +jobs: + report: + name: Test Report 🧪 + uses: DbUp/Universe/.github/workflows/test-report.yml@main \ No newline at end of file From a586553a2736b40675243234e0efc9227ba1b7e4 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Sat, 20 Jul 2024 11:37:09 +1000 Subject: [PATCH 07/17] Ignored commit that bumps the major version --- GitVersion.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GitVersion.yml b/GitVersion.yml index c311488..98bbd8a 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1 +1,3 @@ -mode: Mainline \ No newline at end of file +mode: Mainline +ignore: + sha: [4b3e9a27e5eabcd29690321ce1a1ae20d0d85afb] \ No newline at end of file From 4a6df7a2a1e5f426d3c7eab20ae9784b5113fc51 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Wed, 24 Jul 2024 15:34:42 +1000 Subject: [PATCH 08/17] Removed a string.Format --- src/dbup-sqlserver/SqlServerExtensions.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/dbup-sqlserver/SqlServerExtensions.cs b/src/dbup-sqlserver/SqlServerExtensions.cs index a1b0d44..a0268c6 100644 --- a/src/dbup-sqlserver/SqlServerExtensions.cs +++ b/src/dbup-sqlserver/SqlServerExtensions.cs @@ -374,11 +374,8 @@ static void GetMasterConnectionStringBuilder(string connectionString, IUpgradeLo static bool DatabaseExists(SqlConnection connection, string databaseName) { - var sqlCommandText = string.Format - ( - @"SELECT TOP 1 case WHEN dbid IS NOT NULL THEN 1 ELSE 0 end FROM sys.sysdatabases WHERE name = '{0}';", - databaseName - ); + var sqlCommandText = + $@"SELECT TOP 1 case WHEN dbid IS NOT NULL THEN 1 ELSE 0 end FROM sys.sysdatabases WHERE name = '{databaseName}';"; // check to see if the database already exists.. using (var command = new SqlCommand(sqlCommandText, connection) From 5dd8b3f201b34d02d707bb816f301516f0f0afd6 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Fri, 26 Jul 2024 09:21:47 +1000 Subject: [PATCH 09/17] Bump to the next beta of dbup-core --- src/Tests/Tests.csproj | 2 +- src/dbup-sqlserver/dbup-sqlserver.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index e986f0f..5d7d135 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index 4eeb19f..698543b 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -23,7 +23,7 @@ - + From c6f95f9621f59ff212ddfb82dddf3650b7d321cc Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Fri, 26 Jul 2024 16:42:14 +1000 Subject: [PATCH 10/17] Forced version to 6.0.0 --- GitVersion.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/GitVersion.yml b/GitVersion.yml index 98bbd8a..9c1685d 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,3 +1,2 @@ mode: Mainline -ignore: - sha: [4b3e9a27e5eabcd29690321ce1a1ae20d0d85afb] \ No newline at end of file +next-version: 6.0.0 \ No newline at end of file From a78bf8578964bb4f68e836a8d7dcd812b44cc10b Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Fri, 26 Jul 2024 17:34:12 +1000 Subject: [PATCH 11/17] Passed `TokenCredential` in for Azure connections --- .../NoPublicApiChanges.Run.approved.cs | 10 ++--- .../AzureSqlConnectionManager.cs | 27 +++++++------ .../AzureSqlServerExtensions.cs | 39 +++++++------------ src/dbup-sqlserver/Properties/AssemblyInfo.cs | 2 +- src/dbup-sqlserver/dbup-sqlserver.csproj | 5 +-- 5 files changed, 32 insertions(+), 51 deletions(-) diff --git a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs index 57a0780..5c750d7 100644 --- a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs +++ b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs @@ -1,12 +1,10 @@ -[assembly: System.CLSCompliantAttribute(true)] +[assembly: System.CLSCompliantAttribute(false)] [assembly: System.Runtime.InteropServices.ComVisibleAttribute(false)] [assembly: System.Runtime.InteropServices.GuidAttribute("8190b40b-ac5b-414f-8a00-9b6a2c12b010")] public static class AzureSqlServerExtensions { - public static DbUp.Builder.UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema) { } - public static DbUp.Builder.UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, string resource) { } - public static DbUp.Builder.UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, string resource, string tenantId, string azureAdInstance = "https://login.microsoftonline.com/") { } + public static DbUp.Builder.UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema = null, Azure.Core.TokenCredential tokenCredential = null, string resource = "https://database.windows.net/", string tenantId = null) { } } public static class SqlServerExtensions { @@ -40,9 +38,7 @@ public enum AzureDatabaseEdition : int } public class AzureSqlConnectionManager : DbUp.Engine.Transactions.DatabaseConnectionManager, DbUp.Engine.Transactions.IConnectionManager { - public AzureSqlConnectionManager(string connectionString) { } - public AzureSqlConnectionManager(string connectionString, string resource) { } - public AzureSqlConnectionManager(string connectionString, string resource, string tenantId, string azureAdInstance = "https://login.microsoftonline.com/") { } + public AzureSqlConnectionManager(string connectionString, Azure.Core.TokenCredential tokenCredential, string resource = "https://database.windows.net/", string tenantId = null) { } public override System.Collections.Generic.IEnumerable SplitScriptIntoCommands(string scriptContents) { } } public class SqlConnectionManager : DbUp.Engine.Transactions.DatabaseConnectionManager, DbUp.Engine.Transactions.IConnectionManager diff --git a/src/dbup-sqlserver/AzureSqlConnectionManager.cs b/src/dbup-sqlserver/AzureSqlConnectionManager.cs index 49805be..3008b01 100644 --- a/src/dbup-sqlserver/AzureSqlConnectionManager.cs +++ b/src/dbup-sqlserver/AzureSqlConnectionManager.cs @@ -1,31 +1,29 @@ using System.Collections.Generic; +using System.Threading; using Microsoft.Data.SqlClient; using DbUp.Engine.Transactions; using DbUp.Support; -using Azure.Identity; using Azure.Core; +using Azure.Identity; namespace DbUp.SqlServer; /// Manages an Azure Sql Server database connection. public class AzureSqlConnectionManager : DatabaseConnectionManager { - public AzureSqlConnectionManager(string connectionString) - : this(connectionString, "https://database.windows.net/", null) - { } - - public AzureSqlConnectionManager(string connectionString, string resource) - : this(connectionString, resource, null) - { } - - public AzureSqlConnectionManager(string connectionString, string resource, string tenantId, string azureAdInstance = "https://login.microsoftonline.com/") + public AzureSqlConnectionManager( + string connectionString, + TokenCredential tokenCredential, + string resource = "https://database.windows.net/", + string tenantId = null + ) : base(new DelegateConnectionFactory((log, dbManager) => { - var tokenProvider = new DefaultAzureCredential(); - var tokenContext = new TokenRequestContext(scopes: new string[] { resource + "/.default" }, tenantId: tenantId); + var tokenContext = + new TokenRequestContext(scopes: new string[] { resource + "/.default" }, tenantId: tenantId); var conn = new SqlConnection(connectionString) { - AccessToken = tokenProvider.GetToken(tokenContext).Token + AccessToken = tokenCredential.GetToken(tokenContext, CancellationToken.None).Token }; if (dbManager.IsScriptOutputLogged) @@ -33,7 +31,8 @@ public AzureSqlConnectionManager(string connectionString, string resource, strin return conn; })) - { } + { + } public override IEnumerable SplitScriptIntoCommands(string scriptContents) { diff --git a/src/dbup-sqlserver/AzureSqlServerExtensions.cs b/src/dbup-sqlserver/AzureSqlServerExtensions.cs index de7aa57..c93c4e8 100644 --- a/src/dbup-sqlserver/AzureSqlServerExtensions.cs +++ b/src/dbup-sqlserver/AzureSqlServerExtensions.cs @@ -1,4 +1,5 @@ -using System; +using Azure.Core; +using Azure.Identity; using DbUp.Builder; using DbUp.SqlServer; @@ -13,33 +14,21 @@ public static class AzureSqlServerExtensions /// Fluent helper type. /// The connection string. /// The SQL schema name to use. Defaults to 'dbo' if . - /// A builder for a database upgrader designed for Azure SQL Server databases. - public static UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this SupportedDatabases supported, string connectionString, string schema) - { - return supported.SqlDatabase(new AzureSqlConnectionManager(connectionString), schema); - } - - /// Creates an upgrader for Azure SQL Databases using Azure AD Integrated Security. - /// Fluent helper type. - /// The connection string. - /// The SQL schema name to use. Defaults to 'dbo' if . - /// A builder for a database upgrader designed for Azure SQL Server databases. - public static UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this SupportedDatabases supported, string connectionString, string schema, string resource) - { - return AzureSqlDatabaseWithIntegratedSecurity(supported, connectionString, schema, resource, null); - } - - /// Creates an upgrader for Azure SQL Databases using Azure AD Integrated Security. - /// Fluent helper type. - /// The connection string. - /// The SQL schema name to use. Defaults to 'dbo' if . - /// Resource to access. e.g. https://management.azure.com/. + /// The credentials used. If null, 'DefaultAzureCredential' is used. + /// Resource to access. e.g. https://database.windows.net/. /// If not specified, default tenant is used. Managed Service Identity REST protocols do not accept tenantId, so this can only be used with certificate and client secret based authentication. - /// Specify a value for clouds other than the Public Cloud. /// A builder for a database upgrader designed for Azure SQL Server databases. - public static UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity(this SupportedDatabases supported, string connectionString, string schema, string resource, string tenantId, string azureAdInstance = "https://login.microsoftonline.com/") + public static UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSecurity( + this SupportedDatabases supported, + string connectionString, + string schema = null, + TokenCredential tokenCredential = null, + string resource = "https://database.windows.net/", + string tenantId = null + ) { - return supported.SqlDatabase(new AzureSqlConnectionManager(connectionString, resource, tenantId, azureAdInstance), schema); + return supported.SqlDatabase( + new AzureSqlConnectionManager(connectionString, tokenCredential ?? new DefaultAzureCredential(), resource, tenantId), schema); } } #pragma warning restore CA1050 // Declare types in namespaces diff --git a/src/dbup-sqlserver/Properties/AssemblyInfo.cs b/src/dbup-sqlserver/Properties/AssemblyInfo.cs index 2cb2224..57508d6 100644 --- a/src/dbup-sqlserver/Properties/AssemblyInfo.cs +++ b/src/dbup-sqlserver/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)] -[assembly: CLSCompliant(true)] +[assembly: CLSCompliant(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("8190b40b-ac5b-414f-8a00-9b6a2c12b010")] diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index 249f0df..14714a7 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -25,11 +25,8 @@ - - - - + From 0cbdb1f4158848793c6b6e86c35fff4fc9ca8952 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Fri, 26 Jul 2024 17:35:04 +1000 Subject: [PATCH 12/17] Undid accidental downgrade --- src/dbup-sqlserver/dbup-sqlserver.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index 14714a7..f47007e 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -25,7 +25,7 @@ - + From 373de57547f38d988495ae61069403ee6d2ed139 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Sat, 27 Jul 2024 15:14:16 +1000 Subject: [PATCH 13/17] Removed unneeded reference --- src/dbup-sqlserver/dbup-sqlserver.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index f47007e..ad90858 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -26,7 +26,6 @@ - From b88e44aa4d73a6762157beff20ba0316607670d4 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Mon, 30 Sep 2024 17:18:43 +1000 Subject: [PATCH 14/17] Upgraded to SqlClient 5.2.2 --- src/dbup-sqlserver/dbup-sqlserver.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index ad90858..d3fb7da 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -25,7 +25,7 @@ - + From 1363fa329f15bce85eac09e3ec8f075cb7fe57d3 Mon Sep 17 00:00:00 2001 From: Jeremy Morton Date: Sat, 18 Feb 2023 14:32:36 +0000 Subject: [PATCH 15/17] Allow custom DB creation script to be passed. --- .../NoPublicApiChanges.Run.approved.cs | 21 +-- src/dbup-sqlserver/SqlServerExtensions.cs | 139 +++++++++++------- 2 files changed, 98 insertions(+), 62 deletions(-) diff --git a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs index 5c750d7..11b0244 100644 --- a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs +++ b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs @@ -1,4 +1,4 @@ -[assembly: System.CLSCompliantAttribute(false)] +[assembly: System.CLSCompliantAttribute(false)] [assembly: System.Runtime.InteropServices.ComVisibleAttribute(false)] [assembly: System.Runtime.InteropServices.GuidAttribute("8190b40b-ac5b-414f-8a00-9b6a2c12b010")] @@ -9,23 +9,24 @@ public static DbUp.Builder.UpgradeEngineBuilder AzureSqlDatabaseWithIntegratedSe public static class SqlServerExtensions { public static DbUp.Builder.UpgradeEngineBuilder JournalToSqlTable(this DbUp.Builder.UpgradeEngineBuilder builder, string schema, string table) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, string collation) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, string collation) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition, string collation) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition, string collation) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout = -1, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition = 0, string collation = null, System.Collections.Generic.IList createDbSqlCommands = null, bool checkOnly = false) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger, int timeout = -1, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition = 0, string collation = null, System.Collections.Generic.IList createDbSqlCommands = null, bool checkOnly = false) { } public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString) { } public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema) { } public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, DbUp.Engine.Transactions.IConnectionManager connectionManager, string schema = null) { } [System.ObsoleteAttribute("Use "AzureSqlDatabaseWithIntegratedSecurity(this SupportedDatabases, string, string)" if passing "true" to "useAzureSqlIntegratedSecurity".")] public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema, bool useAzureSqlIntegratedSecurity) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString) { } public static void SqlDatabase(this DbUp.SupportedDatabasesForDropDatabase supported, string connectionString) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, string collation) { } public static void SqlDatabase(this DbUp.SupportedDatabasesForDropDatabase supported, string connectionString, int commandTimeout) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, string collation) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition, string collation) { } public static void SqlDatabase(this DbUp.SupportedDatabasesForDropDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger, int timeout = -1) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition, string collation) { } - public static void SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger, int timeout = -1, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition = 0, string collation = null) { } } namespace DbUp.SqlServer { diff --git a/src/dbup-sqlserver/SqlServerExtensions.cs b/src/dbup-sqlserver/SqlServerExtensions.cs index a0268c6..4117b34 100644 --- a/src/dbup-sqlserver/SqlServerExtensions.cs +++ b/src/dbup-sqlserver/SqlServerExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data; using Microsoft.Data.SqlClient; using DbUp; @@ -110,10 +111,10 @@ public static UpgradeEngineBuilder JournalToSqlTable(this UpgradeEngineBuilder b /// /// Fluent helper type. /// The connection string. - /// - public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString) + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString) { - SqlDatabase(supported, connectionString, new ConsoleUpgradeLog()); + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog()); } /// @@ -122,10 +123,10 @@ public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// Fluent helper type. /// The connection string. /// Azure edition to Create - /// - public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, AzureDatabaseEdition azureDatabaseEdition) + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, AzureDatabaseEdition azureDatabaseEdition) { - SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), -1, azureDatabaseEdition); + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), -1, azureDatabaseEdition); } /// @@ -134,10 +135,10 @@ public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// Fluent helper type. /// The connection string. /// Use this to set the command time out for creating a database in case you're encountering a time out in this operation. - /// - public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout) + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout) { - SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout); + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout); } /// @@ -146,10 +147,10 @@ public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// Fluent helper type. /// The connection string. /// The collation name to set during database creation - /// - public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, string collation) + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, string collation) { - SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), collation: collation); + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), collation: collation); } /// @@ -159,10 +160,10 @@ public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// The connection string. /// Use this to set the command time out for creating a database in case you're encountering a time out in this operation. /// Azure edition to Create - /// - public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, AzureDatabaseEdition azureDatabaseEdition) + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, AzureDatabaseEdition azureDatabaseEdition) { - SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout, azureDatabaseEdition); + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout, azureDatabaseEdition); } /// @@ -172,10 +173,10 @@ public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// The connection string. /// Use this to set the command time out for creating a database in case you're encountering a time out in this operation. /// The collation name to set during database creation - /// - public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, string collation) + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, string collation) { - SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout, collation: collation); + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout, collation: collation); } /// @@ -185,10 +186,10 @@ public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// The connection string. /// Azure edition to Create /// The collation name to set during database creation - /// - public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, AzureDatabaseEdition azureDatabaseEdition, string collation) + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, AzureDatabaseEdition azureDatabaseEdition, string collation) { - SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), azureDatabaseEdition: azureDatabaseEdition, collation: collation); + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), azureDatabaseEdition: azureDatabaseEdition, collation: collation); } /// @@ -199,10 +200,26 @@ public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// Use this to set the command time out for creating a database in case you're encountering a time out in this operation. /// Azure edition to Create /// The collation name to set during database creation - /// - public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, AzureDatabaseEdition azureDatabaseEdition, string collation) + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, AzureDatabaseEdition azureDatabaseEdition, string collation) { - SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout, azureDatabaseEdition, collation); + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout, azureDatabaseEdition, collation); + } + + /// + /// Ensures that the database specified in the connection string exists. + /// + /// Fluent helper type. + /// The connection string. + /// Use this to set the command time out for creating a database in case you're encountering a time out in this operation. + /// Azure edition to Create + /// The collation name to set during database creation + /// A list of custom SQL commands that will be used to create the database. + /// If true, only checks whether the database would've been created but does not perform the creation. + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout = -1, AzureDatabaseEdition azureDatabaseEdition = AzureDatabaseEdition.None, string collation = null, IList createDbSqlCommands = null, bool checkOnly = false) + { + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout, azureDatabaseEdition, collation, createDbSqlCommands, checkOnly); } /// @@ -214,14 +231,18 @@ public static void SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// Use this to set the command time out for creating a database in case you're encountering a time out in this operation. /// Use to indicate that the SQL server database is in Azure /// The collation name to set during database creation - /// - public static void SqlDatabase( + /// A list of custom SQL commands that will be used to create the database. + /// If true, only checks whether the database would've been created but does not perform the creation. + /// True if the database was (or would've been) created; otherwise false. + public static bool SqlDatabase( this SupportedDatabasesForEnsureDatabase supported, string connectionString, IUpgradeLog logger, int timeout = -1, AzureDatabaseEdition azureDatabaseEdition = AzureDatabaseEdition.None, - string collation = null) + string collation = null, + IList createDbSqlCommands = null, + bool checkOnly = false) { GetMasterConnectionStringBuilder(connectionString, logger, out var masterConnectionString, out var databaseName); @@ -235,48 +256,62 @@ public static void SqlDatabase( { // Failed to connect to master, lets try direct if (DatabaseExistsIfConnectedToDirectly(logger, connectionString, databaseName)) - return; + return false; throw; } if (DatabaseExists(connection, databaseName)) - return; + return false; - var collationString = string.IsNullOrEmpty(collation) ? "" : $@" COLLATE {collation}"; - var sqlCommandText = $@"create database [{databaseName}]{collationString}"; + if (checkOnly) + return true; - switch (azureDatabaseEdition) + if (createDbSqlCommands == null) { - case AzureDatabaseEdition.None: - sqlCommandText += ";"; - break; - case AzureDatabaseEdition.Basic: - sqlCommandText += " ( EDITION = ''basic'' );"; - break; - case AzureDatabaseEdition.Standard: - sqlCommandText += " ( EDITION = ''standard'' );"; - break; - case AzureDatabaseEdition.Premium: - sqlCommandText += " ( EDITION = ''premium'' );"; - break; + createDbSqlCommands = new List(); + var collationString = string.IsNullOrEmpty(collation) ? "" : $@" COLLATE {collation}"; + var sqlCommandText = $@"create database [{databaseName}]{collationString}"; + + switch (azureDatabaseEdition) + { + case AzureDatabaseEdition.None: + sqlCommandText += ";"; + break; + case AzureDatabaseEdition.Basic: + sqlCommandText += " ( EDITION = ''basic'' );"; + break; + case AzureDatabaseEdition.Standard: + sqlCommandText += " ( EDITION = ''standard'' );"; + break; + case AzureDatabaseEdition.Premium: + sqlCommandText += " ( EDITION = ''premium'' );"; + break; + } + + createDbSqlCommands.Add(sqlCommandText); } // Create the database... - using (var command = new SqlCommand(sqlCommandText, connection) + foreach (var sqlCommandText in createDbSqlCommands) { - CommandType = CommandType.Text - }) - { - if (timeout >= 0) + using (var command = new SqlCommand(sqlCommandText, connection) { - command.CommandTimeout = timeout; - } + CommandType = CommandType.Text + }) + { + if (timeout >= 0) + { + command.CommandTimeout = timeout; + } - command.ExecuteNonQuery(); + command.ExecuteNonQuery(); + } } logger.LogInformation(@"Created database {0}", databaseName); + + return true; } } From c78397f24eae71bf1a557e845772b9cd1afa1c9f Mon Sep 17 00:00:00 2001 From: Jeremy Morton Date: Sat, 18 Feb 2023 14:54:35 +0000 Subject: [PATCH 16/17] Use factory to generate DB creation script instead. # Conflicts: # src/dbup-tests/Support/SqlServer/ApprovalFiles/dbup-sqlserver.netfx.approved.cs --- .../NoPublicApiChanges.Run.approved.cs | 4 ++-- src/dbup-sqlserver/SqlServerExtensions.cs | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs index 11b0244..c0b0bcb 100644 --- a/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs +++ b/src/Tests/ApprovalFiles/NoPublicApiChanges.Run.approved.cs @@ -17,8 +17,8 @@ public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase sup public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, string collation) { } public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition, string collation) { } public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition, string collation) { } - public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout = -1, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition = 0, string collation = null, System.Collections.Generic.IList createDbSqlCommands = null, bool checkOnly = false) { } - public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger, int timeout = -1, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition = 0, string collation = null, System.Collections.Generic.IList createDbSqlCommands = null, bool checkOnly = false) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout = -1, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition = 0, string collation = null, System.Func> createDbSqlCommandsFactory = null, bool checkOnly = false) { } + public static bool SqlDatabase(this DbUp.SupportedDatabasesForEnsureDatabase supported, string connectionString, DbUp.Engine.Output.IUpgradeLog logger, int timeout = -1, DbUp.SqlServer.AzureDatabaseEdition azureDatabaseEdition = 0, string collation = null, System.Func> createDbSqlCommandsFactory = null, bool checkOnly = false) { } public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString) { } public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, string connectionString, string schema) { } public static DbUp.Builder.UpgradeEngineBuilder SqlDatabase(this DbUp.Builder.SupportedDatabases supported, DbUp.Engine.Transactions.IConnectionManager connectionManager, string schema = null) { } diff --git a/src/dbup-sqlserver/SqlServerExtensions.cs b/src/dbup-sqlserver/SqlServerExtensions.cs index 4117b34..528c97a 100644 --- a/src/dbup-sqlserver/SqlServerExtensions.cs +++ b/src/dbup-sqlserver/SqlServerExtensions.cs @@ -214,12 +214,12 @@ public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// Use this to set the command time out for creating a database in case you're encountering a time out in this operation. /// Azure edition to Create /// The collation name to set during database creation - /// A list of custom SQL commands that will be used to create the database. + /// A factory receiving the DB name, and returning a list of custom SQL commands that will be used to create the database. /// If true, only checks whether the database would've been created but does not perform the creation. /// True if the database was (or would've been) created; otherwise false. - public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout = -1, AzureDatabaseEdition azureDatabaseEdition = AzureDatabaseEdition.None, string collation = null, IList createDbSqlCommands = null, bool checkOnly = false) + public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supported, string connectionString, int commandTimeout = -1, AzureDatabaseEdition azureDatabaseEdition = AzureDatabaseEdition.None, string collation = null, Func> createDbSqlCommandsFactory = null, bool checkOnly = false) { - return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout, azureDatabaseEdition, collation, createDbSqlCommands, checkOnly); + return SqlDatabase(supported, connectionString, new ConsoleUpgradeLog(), commandTimeout, azureDatabaseEdition, collation, createDbSqlCommandsFactory, checkOnly); } /// @@ -231,7 +231,7 @@ public static bool SqlDatabase(this SupportedDatabasesForEnsureDatabase supporte /// Use this to set the command time out for creating a database in case you're encountering a time out in this operation. /// Use to indicate that the SQL server database is in Azure /// The collation name to set during database creation - /// A list of custom SQL commands that will be used to create the database. + /// A factory receiving the DB name, and returning a list of custom SQL commands that will be used to create the database. /// If true, only checks whether the database would've been created but does not perform the creation. /// True if the database was (or would've been) created; otherwise false. public static bool SqlDatabase( @@ -241,7 +241,7 @@ public static bool SqlDatabase( int timeout = -1, AzureDatabaseEdition azureDatabaseEdition = AzureDatabaseEdition.None, string collation = null, - IList createDbSqlCommands = null, + Func> createDbSqlCommandsFactory = null, bool checkOnly = false) { GetMasterConnectionStringBuilder(connectionString, logger, out var masterConnectionString, out var databaseName); @@ -267,7 +267,8 @@ public static bool SqlDatabase( if (checkOnly) return true; - if (createDbSqlCommands == null) + IList createDbSqlCommands; + if (createDbSqlCommandsFactory == null) { createDbSqlCommands = new List(); var collationString = string.IsNullOrEmpty(collation) ? "" : $@" COLLATE {collation}"; @@ -291,6 +292,10 @@ public static bool SqlDatabase( createDbSqlCommands.Add(sqlCommandText); } + else + { + createDbSqlCommands = createDbSqlCommandsFactory(databaseName); + } // Create the database... foreach (var sqlCommandText in createDbSqlCommands) From bdd5c0ae01f6ab05ad3da6f2cf384c616bae476f Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Tue, 22 Oct 2024 21:40:36 +1000 Subject: [PATCH 17/17] Update to dbup-core 6.0 --- src/dbup-sqlserver/dbup-sqlserver.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dbup-sqlserver/dbup-sqlserver.csproj b/src/dbup-sqlserver/dbup-sqlserver.csproj index d3fb7da..8340f0e 100644 --- a/src/dbup-sqlserver/dbup-sqlserver.csproj +++ b/src/dbup-sqlserver/dbup-sqlserver.csproj @@ -23,8 +23,7 @@ - - +