diff --git a/README.md b/README.md index 6c73d90..8b0b9b3 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,8 @@ For migration authoring, use the local tool command form: dotnet dotnet-ef migrations add --project RpgRoller/RpgRoller.csproj --startup-project RpgRoller/RpgRoller.csproj ``` +For SQLite migrations, avoid `migrationBuilder.Sql(...)` in the same migration step that rebuilds a table for schema changes; prefer column defaults or a follow-up migration so EF Core does not warn about raw SQL executing while a rebuilt table is still pending. + ## Frontend Runtime - Runtime frontend is Blazor Server with interactive components. diff --git a/RpgRoller.Tests/HostingCoverageTests.cs b/RpgRoller.Tests/HostingCoverageTests.cs index 8af87a4..18f98ef 100644 --- a/RpgRoller.Tests/HostingCoverageTests.cs +++ b/RpgRoller.Tests/HostingCoverageTests.cs @@ -1,6 +1,8 @@ using Microsoft.Data.Sqlite; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -203,6 +205,23 @@ public sealed class HostingCoverageTests Assert.Equal(1, rolemasterHistoryCount); } + [Fact] + public void AuthorizationRolesAndCampaignDeletion_MigrationScript_DoesNotMixUsersSqlIntoCharactersRebuild() + { + var dbPath = Path.Combine(Path.GetTempPath(), $"rpgroller-migration-script-{Guid.NewGuid():N}.db"); + var options = new DbContextOptionsBuilder().UseSqlite($"Data Source={dbPath}").Options; + + using var db = new RpgRollerDbContext(options); + var migrator = db.GetService(); + var script = migrator.GenerateScript( + fromMigration: "20260226131003_AddSkillGroupPrototypes", + toMigration: "20260226160859_AddAuthorizationRolesAndCampaignDeletion"); + + Assert.Contains("""ALTER TABLE "Users" ADD "Roles" TEXT NOT NULL DEFAULT 'admin';""", script); + Assert.Contains("""CREATE TABLE "ef_temp_Characters" (""", script); + Assert.DoesNotContain("UPDATE Users", script); + } + [Fact] public void InitializeRpgRollerState_MigratesCopiedDevelopmentDatabaseAndPreservesD6Rolling() { diff --git a/RpgRoller/Migrations/20260226160859_AddAuthorizationRolesAndCampaignDeletion.cs b/RpgRoller/Migrations/20260226160859_AddAuthorizationRolesAndCampaignDeletion.cs index 883ed43..8fee79a 100644 --- a/RpgRoller/Migrations/20260226160859_AddAuthorizationRolesAndCampaignDeletion.cs +++ b/RpgRoller/Migrations/20260226160859_AddAuthorizationRolesAndCampaignDeletion.cs @@ -26,12 +26,6 @@ namespace RpgRoller.Migrations nullable: true, oldClrType: typeof(Guid), oldType: "TEXT"); - - migrationBuilder.Sql(""" - UPDATE Users - SET Roles = 'admin' - WHERE Roles IS NULL OR TRIM(Roles) = ''; - """); } ///