diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b89e004..d4e2ad1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -17,7 +17,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x + dotnet-version: | + 6.0.x + 7.0.x - name: Restore dependencies run: dotnet restore diff --git a/CHANGELOG.md b/CHANGELOG.md index d1506ab..39ce0e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Represents the **NuGet** versions. +## v2.3.5 +- *Enhancement:* Updated `CoreEx` to version `3.0.0`. +- *Enhancement:* Updated all dependent packages to latest versions. +- *Enhancement:* Added `net6.0` and `net7.0` support in addition to [.NET Standard](https://learn.microsoft.com/en-us/dotnet/standard/net-standard#when-to-target-net50-or-net60-vs-netstandard) to the `DbEx` packages. This will allow access to additional features per version where required, and overall performance improvements. +- *Enhancement:* Included C# code-generation templates updated; target `net6.0`+ only. + ## v2.3.4 - *Fixed:* `MigrationArgsBase.Assemblies` internal list management simplified; all order/sequencing managed within `DatabaseMigrationBase` implementation to limit issues. Added a new `AddAssemblyAfter` to support explicit positioning where needed. diff --git a/Common.targets b/Common.targets index e3ebe85..c437e82 100644 --- a/Common.targets +++ b/Common.targets @@ -1,6 +1,6 @@ - 2.3.4 + 2.3.5 preview Avanade Avanade diff --git a/DbEx.sln b/DbEx.sln index f88ee20..42c3455 100644 --- a/DbEx.sln +++ b/DbEx.sln @@ -39,9 +39,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{BB01353C-4 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbEx.SqlServer", "src\DbEx.SqlServer\DbEx.SqlServer.csproj", "{74DF6A5E-4F95-467A-8F64-5A4DBC3AAFFC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DbEx.MySql", "src\DbEx.MySql\DbEx.MySql.csproj", "{2B2BD40D-46FD-4582-994D-39D8056DE55E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbEx.MySql", "src\DbEx.MySql\DbEx.MySql.csproj", "{2B2BD40D-46FD-4582-994D-39D8056DE55E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DbEx.Test.MySqlConsole", "tests\DbEx.Test.MySqlConsole\DbEx.Test.MySqlConsole.csproj", "{80EF0604-F641-4D01-9922-0162D0C69E02}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbEx.Test.MySqlConsole", "tests\DbEx.Test.MySqlConsole\DbEx.Test.MySqlConsole.csproj", "{80EF0604-F641-4D01-9922-0162D0C69E02}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Github Actions", "Github Actions", "{B208377A-6E7E-4E59-AD2F-34C9CB9A5E81}" + ProjectSection(SolutionItems) = preProject + .github\workflows\CI.yml = .github\workflows\CI.yml + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/DbEx.MySql/DbEx.MySql.csproj b/src/DbEx.MySql/DbEx.MySql.csproj index 7c014e1..2ae9051 100644 --- a/src/DbEx.MySql/DbEx.MySql.csproj +++ b/src/DbEx.MySql/DbEx.MySql.csproj @@ -1,7 +1,7 @@ - + - netstandard2.1 + net6.0;net7.0;netstandard2.1 DbEx.MySql DbEx DbEx MySQL Migration Tool. @@ -39,9 +39,9 @@ - - - + + + diff --git a/src/DbEx.MySql/MySqlSchemaConfig.cs b/src/DbEx.MySql/MySqlSchemaConfig.cs index 7144d9c..6b414c0 100644 --- a/src/DbEx.MySql/MySqlSchemaConfig.cs +++ b/src/DbEx.MySql/MySqlSchemaConfig.cs @@ -199,7 +199,7 @@ public override string ToFormattedSqlType(DbColumnSchema schema, bool includeNul Guid => $"'{value}'", DateTime dt => $"'{dt.ToString(dataParserArgs.DateTimeFormat, System.Globalization.CultureInfo.InvariantCulture)}'", DateTimeOffset dto => $"'{dto.ToString(dataParserArgs.DateTimeFormat, System.Globalization.CultureInfo.InvariantCulture)}'", - _ => value.ToString() + _ => value.ToString()! }; /// diff --git a/src/DbEx.SqlServer/DbEx.SqlServer.csproj b/src/DbEx.SqlServer/DbEx.SqlServer.csproj index 8fdfce5..184f34d 100644 --- a/src/DbEx.SqlServer/DbEx.SqlServer.csproj +++ b/src/DbEx.SqlServer/DbEx.SqlServer.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + net6.0;net7.0;netstandard2.1 DbEx.SqlServer DbEx DbEx SQL Server Migration Tool. @@ -30,9 +30,9 @@ - - - + + + diff --git a/src/DbEx.SqlServer/SqlServerSchemaConfig.cs b/src/DbEx.SqlServer/SqlServerSchemaConfig.cs index e11049c..258bd21 100644 --- a/src/DbEx.SqlServer/SqlServerSchemaConfig.cs +++ b/src/DbEx.SqlServer/SqlServerSchemaConfig.cs @@ -4,7 +4,6 @@ using DbEx.DbSchema; using DbEx.Migration; using DbEx.Migration.Data; -using OnRamp.Utility; using System; using System.Collections.Generic; using System.Linq; @@ -219,7 +218,7 @@ public override string ToFormattedSqlType(DbColumnSchema schema, bool includeNul Guid => $"'{value}'", DateTime dt => $"'{dt.ToString(dataParserArgs.DateTimeFormat, System.Globalization.CultureInfo.InvariantCulture)}'", DateTimeOffset dto => $"'{dto.ToString(dataParserArgs.DateTimeFormat, System.Globalization.CultureInfo.InvariantCulture)}'", - _ => value.ToString() + _ => value.ToString()! }; /// diff --git a/src/DbEx.SqlServer/Templates/EventOutboxDequeue_cs.hbs b/src/DbEx.SqlServer/Templates/EventOutboxDequeue_cs.hbs index 93729f5..9941845 100644 --- a/src/DbEx.SqlServer/Templates/EventOutboxDequeue_cs.hbs +++ b/src/DbEx.SqlServer/Templates/EventOutboxDequeue_cs.hbs @@ -3,35 +3,29 @@ * This file is automatically generated; any changes will be lost. */ +{{#if Root.PreprocessorDirectives}} #nullable enable #pragma warning disable -using CoreEx.Database; -using CoreEx.Database.SqlServer.Outbox; -using CoreEx.Events; -using Microsoft.Extensions.Logging; -using System.Collections.Generic; -using System.Data; +{{/if}} +namespace {{NamespaceOutbox}}.Data; -namespace {{NamespaceOutbox}}.Data +/// +/// Provides the database outbox enqueue . +/// +public sealed class EventOutboxDequeue : EventOutboxDequeueBase { /// - /// Provides the database outbox enqueue . + /// Initializes a new instance of the class. /// - public sealed class EventOutboxDequeue : EventOutboxDequeueBase - { - /// - /// Initializes a new instance of the class. - /// - /// The . - /// The . - /// The . - public EventOutboxDequeue(IDatabase database, IEventSender eventSender, ILogger logger) : base(database, eventSender, logger) { } + /// The . + /// The . + /// The . + public EventOutboxDequeue(IDatabase database, IEventSender eventSender, ILogger logger) : base(database, eventSender, logger) { } - /// - protected override string DequeueStoredProcedure => "[{{OutboxSchema}}].[{{OutboxDequeueStoredProcedure}}]"; - } -} + /// + protected override string DequeueStoredProcedure => "[{{OutboxSchema}}].[{{OutboxDequeueStoredProcedure}}]"; +}{{#if Root.PreprocessorDirectives}} #pragma warning restore -#nullable restore \ No newline at end of file +#nullable restore{{/if}} \ No newline at end of file diff --git a/src/DbEx.SqlServer/Templates/EventOutboxEnqueue_cs.hbs b/src/DbEx.SqlServer/Templates/EventOutboxEnqueue_cs.hbs index 266a273..a582cdd 100644 --- a/src/DbEx.SqlServer/Templates/EventOutboxEnqueue_cs.hbs +++ b/src/DbEx.SqlServer/Templates/EventOutboxEnqueue_cs.hbs @@ -3,36 +3,31 @@ * This file is automatically generated; any changes will be lost. */ +{{#if Root.PreprocessorDirectives}} #nullable enable #pragma warning disable -using CoreEx.Database; -using CoreEx.Database.SqlServer.Outbox; -using Microsoft.Extensions.Logging; -using System.Collections.Generic; -using System.Data; +{{/if}} +namespace {{NamespaceOutbox}}.Data; -namespace {{NamespaceOutbox}}.Data +/// +/// Provides the database outbox enqueue . +/// +public sealed class EventOutboxEnqueue : EventOutboxEnqueueBase { /// - /// Provides the database outbox enqueue . + /// Initializes a new instance of the class. /// - public sealed class EventOutboxEnqueue : EventOutboxEnqueueBase - { - /// - /// Initializes a new instance of the class. - /// - /// The . - /// The . - public EventOutboxEnqueue(IDatabase database, ILogger logger) : base(database, logger) { } + /// The . + /// The . + public EventOutboxEnqueue(IDatabase database, ILogger logger) : base(database, logger) { } - /// - protected override string DbTvpTypeName => "[{{OutboxSchema}}].[udt{{OutboxTable}}List]"; + /// + protected override string DbTvpTypeName => "[{{OutboxSchema}}].[udt{{OutboxTable}}List]"; - /// - protected override string EnqueueStoredProcedure => "[{{OutboxSchema}}].[{{OutboxEnqueueStoredProcedure}}]"; - } -} + /// + protected override string EnqueueStoredProcedure => "[{{OutboxSchema}}].[{{OutboxEnqueueStoredProcedure}}]"; +}{{#if Root.PreprocessorDirectives}} #pragma warning restore -#nullable restore \ No newline at end of file +#nullable restore{{/if}} \ No newline at end of file diff --git a/src/DbEx/Console/MigrationConsoleBase.cs b/src/DbEx/Console/MigrationConsoleBase.cs index 601d8de..83eab1f 100644 --- a/src/DbEx/Console/MigrationConsoleBase.cs +++ b/src/DbEx/Console/MigrationConsoleBase.cs @@ -252,7 +252,7 @@ public async Task RunAsync(string[] args, CancellationToken cancellationTok /// /// The option name. /// The action to perform where is provided. - protected void UpdateStringOption(string option, Action action) + protected void UpdateStringOption(string option, Action action) { var co = GetCommandOption(option); if (co != null && co.HasValue()) diff --git a/src/DbEx/DbEx.csproj b/src/DbEx/DbEx.csproj index 61e2211..559a171 100644 --- a/src/DbEx/DbEx.csproj +++ b/src/DbEx/DbEx.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + net6.0;net7.0;netstandard2.1 DbEx DbEx DbEx Database Migration Tool. @@ -21,9 +21,9 @@ - - - + + + diff --git a/src/DbEx/Migration/Data/DataTable.cs b/src/DbEx/Migration/Data/DataTable.cs index 5bec5b0..145dbad 100644 --- a/src/DbEx/Migration/Data/DataTable.cs +++ b/src/DbEx/Migration/Data/DataTable.cs @@ -41,8 +41,7 @@ internal DataTable(DataParser parser, string schema, string name) SchemaTableName = $"'{(schema == string.Empty ? name : $"{schema}.{name}")}'"; - DbTable = Parser.DbTables.Where(t => (!Parser.DatabaseSchemaConfig.SupportsSchema || t.Schema == schema) && t.Name == name).SingleOrDefault(); - if (DbTable == null) + DbTable = Parser.DbTables.Where(t => (!Parser.DatabaseSchemaConfig.SupportsSchema || t.Schema == schema) && t.Name == name).SingleOrDefault() ?? throw new DataParserException($"Table {SchemaTableName} does not exist within the specified database."); // Check that an identifier generator can be used. diff --git a/src/DbEx/Migration/DatabaseMigrationBase.cs b/src/DbEx/Migration/DatabaseMigrationBase.cs index e269f1e..3b7f041 100644 --- a/src/DbEx/Migration/DatabaseMigrationBase.cs +++ b/src/DbEx/Migration/DatabaseMigrationBase.cs @@ -235,7 +235,7 @@ private void PreExecutionInitialization() _hasInitialized = true; var list = (List)Namespaces; - Args.ProbeAssemblies.ForEach(x => list.Add(x.GetName().Name)); + Args.ProbeAssemblies.ForEach(x => list.Add(x.GetName().Name!)); // Walk the assembly hierarchy. var alist = new List(); @@ -246,7 +246,7 @@ private void PreExecutionInitialization() alist.Add(type.Assembly); type = type.BaseType; - } while (type != typeof(object)); + } while (type != null && type != typeof(object)); var list2 = (List)ArtefactResourceAssemblies; list2.AddRange(alist); @@ -524,7 +524,7 @@ private async Task DatabaseSchemaAsync(CancellationToken cancellationToken { foreach (var fi in di.GetFiles("*.sql", SearchOption.AllDirectories)) { - var rn = $"{fi.FullName[(Args.OutputDirectory.Parent.FullName.Length + 1)..]}".Replace(' ', '_').Replace('-', '_').Replace('\\', '.').Replace('/', '.'); + var rn = $"{fi.FullName[((Args.OutputDirectory?.Parent?.FullName.Length + 1) ?? 0)..]}".Replace(' ', '_').Replace('-', '_').Replace('\\', '.').Replace('/', '.'); scripts.Add(new DatabaseMigrationScript(fi, rn)); } } @@ -673,7 +673,7 @@ protected virtual async Task DatabaseResetAsync(CancellationToken cancella var sql = cg.Generate(delete); using var sr2 = new StringReader(sql); - string line; + string? line; while ((line = sr2.ReadLine()) != null) { Logger.LogInformation("{Content}", $" {line}"); @@ -876,7 +876,7 @@ private async Task CreateScriptInternalAsync(string? name, IDictionary ExecuteSqlStatementsInternalAsync(string[]? statements, /// The SQL command. /// The resulting SQL command with runtime replacements make. public string ReplaceSqlRuntimeParameters(string sql) => Args.Parameters.Count == 0 - ? sql : Regex.Replace(sql, "(" + string.Join("|", Args.Parameters.Select(x => $"{{{{{x.Key}}}}}").ToArray()) + ")", m => Args.Parameters.TryGetValue(m.Value[2..^2], out var pv) - ? pv?.ToString() : throw new InvalidOperationException($"Runtime Parameter '{m.Value}' found within SQL command; a corresponding Parameter value has not been configured.")); + ? sql : Regex.Replace(sql, "(" + string.Join("|", Args.Parameters.Select(x => $"{{{{{x.Key}}}}}").ToArray()) + ")", + m => Args.Parameters.TryGetValue(m.Value[2..^2], out var pv) ? pv?.ToString()! : throw new InvalidOperationException($"Runtime Parameter '{m.Value}' found within SQL command; a corresponding Parameter value has not been configured.")); /// public void Dispose() diff --git a/src/DbEx/Migration/DatabaseMigrationScript.cs b/src/DbEx/Migration/DatabaseMigrationScript.cs index e703c0f..feb7585 100644 --- a/src/DbEx/Migration/DatabaseMigrationScript.cs +++ b/src/DbEx/Migration/DatabaseMigrationScript.cs @@ -76,6 +76,6 @@ public DatabaseMigrationScript(string sql, string name) /// public StreamReader GetStreamReader() => _assembly is not null ? new StreamReader(_assembly!.GetManifestResourceStream(Name)!) - : (_file is not null ? _file!.OpenText() : new StreamReader(new MemoryStream(Encoding.Default.GetBytes(_sql)))); + : (_file is not null ? _file!.OpenText() : new StreamReader(new MemoryStream(Encoding.Default.GetBytes(_sql!)))); } } \ No newline at end of file diff --git a/src/DbEx/Migration/StringLogger.cs b/src/DbEx/Migration/StringLogger.cs index 9ad56c5..2a6923c 100644 --- a/src/DbEx/Migration/StringLogger.cs +++ b/src/DbEx/Migration/StringLogger.cs @@ -11,11 +11,15 @@ namespace DbEx.Migration /// internal class StringLogger : ILogger { - private readonly StringBuilder _stringBuilder = new StringBuilder(); + private readonly StringBuilder _stringBuilder = new(); private readonly IExternalScopeProvider _scopeProvider = new LoggerExternalScopeProvider(); /// +#if NET7_0_OR_GREATER + public IDisposable BeginScope(TState state) where TState : notnull => _scopeProvider.Push(state); +#else public IDisposable BeginScope(TState state) => _scopeProvider.Push(state); +#endif /// public bool IsEnabled(LogLevel logLevel) => true; diff --git a/tests/DbEx.Test.OutboxConsole/Generated/EventOutboxDequeue.cs b/tests/DbEx.Test.OutboxConsole/Generated/EventOutboxDequeue.cs index 3659872..1b9a2a7 100644 --- a/tests/DbEx.Test.OutboxConsole/Generated/EventOutboxDequeue.cs +++ b/tests/DbEx.Test.OutboxConsole/Generated/EventOutboxDequeue.cs @@ -2,35 +2,21 @@ * This file is automatically generated; any changes will be lost. */ -#nullable enable -#pragma warning disable +namespace DbEx.Test.OutboxConsole.Data; -using CoreEx.Database; -using CoreEx.Database.SqlServer.Outbox; -using CoreEx.Events; -using Microsoft.Extensions.Logging; -using System.Collections.Generic; -using System.Data; - -namespace DbEx.Test.OutboxConsole.Data +/// +/// Provides the database outbox enqueue . +/// +public sealed class EventOutboxDequeue : EventOutboxDequeueBase { /// - /// Provides the database outbox enqueue . + /// Initializes a new instance of the class. /// - public sealed class EventOutboxDequeue : EventOutboxDequeueBase - { - /// - /// Initializes a new instance of the class. - /// - /// The . - /// The . - /// The . - public EventOutboxDequeue(IDatabase database, IEventSender eventSender, ILogger logger) : base(database, eventSender, logger) { } - - /// - protected override string DequeueStoredProcedure => "[Outbox].[spEventOutboxDequeue]"; - } -} + /// The . + /// The . + /// The . + public EventOutboxDequeue(IDatabase database, IEventSender eventSender, ILogger logger) : base(database, eventSender, logger) { } -#pragma warning restore -#nullable restore \ No newline at end of file + /// + protected override string DequeueStoredProcedure => "[Outbox].[spEventOutboxDequeue]"; +} \ No newline at end of file diff --git a/tests/DbEx.Test.OutboxConsole/Generated/EventOutboxEnqueue.cs b/tests/DbEx.Test.OutboxConsole/Generated/EventOutboxEnqueue.cs index 5ac4c03..27ede78 100644 --- a/tests/DbEx.Test.OutboxConsole/Generated/EventOutboxEnqueue.cs +++ b/tests/DbEx.Test.OutboxConsole/Generated/EventOutboxEnqueue.cs @@ -2,36 +2,23 @@ * This file is automatically generated; any changes will be lost. */ -#nullable enable -#pragma warning disable +namespace DbEx.Test.OutboxConsole.Data; -using CoreEx.Database; -using CoreEx.Database.SqlServer.Outbox; -using Microsoft.Extensions.Logging; -using System.Collections.Generic; -using System.Data; - -namespace DbEx.Test.OutboxConsole.Data +/// +/// Provides the database outbox enqueue . +/// +public sealed class EventOutboxEnqueue : EventOutboxEnqueueBase { /// - /// Provides the database outbox enqueue . + /// Initializes a new instance of the class. /// - public sealed class EventOutboxEnqueue : EventOutboxEnqueueBase - { - /// - /// Initializes a new instance of the class. - /// - /// The . - /// The . - public EventOutboxEnqueue(IDatabase database, ILogger logger) : base(database, logger) { } - - /// - protected override string DbTvpTypeName => "[Outbox].[udtEventOutboxList]"; + /// The . + /// The . + public EventOutboxEnqueue(IDatabase database, ILogger logger) : base(database, logger) { } - /// - protected override string EnqueueStoredProcedure => "[Outbox].[spEventOutboxEnqueue]"; - } -} + /// + protected override string DbTvpTypeName => "[Outbox].[udtEventOutboxList]"; -#pragma warning restore -#nullable restore \ No newline at end of file + /// + protected override string EnqueueStoredProcedure => "[Outbox].[spEventOutboxEnqueue]"; +} \ No newline at end of file diff --git a/tests/DbEx.Test.OutboxConsole/GlobalUsings.cs b/tests/DbEx.Test.OutboxConsole/GlobalUsings.cs new file mode 100644 index 0000000..1d4c00a --- /dev/null +++ b/tests/DbEx.Test.OutboxConsole/GlobalUsings.cs @@ -0,0 +1,4 @@ +global using CoreEx.Database; +global using CoreEx.Database.SqlServer.Outbox; +global using CoreEx.Events; +global using Microsoft.Extensions.Logging; \ No newline at end of file diff --git a/tests/DbEx.Test/DbEx.Test.csproj b/tests/DbEx.Test/DbEx.Test.csproj index 807f2d9..690d579 100644 --- a/tests/DbEx.Test/DbEx.Test.csproj +++ b/tests/DbEx.Test/DbEx.Test.csproj @@ -7,14 +7,14 @@ - - - - - + + + + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/DbEx.Test/appsettings.json b/tests/DbEx.Test/appsettings.json index 12b21fc..92f0a7d 100644 --- a/tests/DbEx.Test/appsettings.json +++ b/tests/DbEx.Test/appsettings.json @@ -5,7 +5,7 @@ "EmptyDb": "Data Source=.;Initial Catalog=DbEx.Empty;Integrated Security=True;TrustServerCertificate=true", "ErrorDb": "Data Source=.;Initial Catalog=DbEx.Error;Integrated Security=True;TrustServerCertificate=true", "ConsoleDb": "Data Source=.;Initial Catalog=DbEx.Console;Integrated Security=True;TrustServerCertificate=true", - "MySqlDb": "Server=localhost; Port=3306; Database=DbEx_Test; Uid=dbuser; Pwd=dbpassword;" + "MySqlDb": "Server=localhost; Port=3306; Database=dbex_test; Uid=dbuser; Pwd=dbpassword;" // WSL ... //"NoneDb": "Data Source=localhost,1433;Initial Catalog=DbEx.None;User id=sa;Password=yourStrong(!)Password;TrustServerCertificate=true",