diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200511012117_SLAddHeartbeat.cs b/src/Tgstation.Server.Host/Database/Migrations/20200511012117_SLAddHeartbeat.cs
index 6e4a97ffef..77fc1f8ad4 100644
--- a/src/Tgstation.Server.Host/Database/Migrations/20200511012117_SLAddHeartbeat.cs
+++ b/src/Tgstation.Server.Host/Database/Migrations/20200511012117_SLAddHeartbeat.cs
@@ -18,7 +18,7 @@ namespace Tgstation.Server.Host.Database.Migrations
name: "HeartbeatSeconds",
table: "DreamDaemonSettings",
nullable: false,
- defaultValue: 0u);
+ defaultValue: 0U);
}
///
@@ -27,9 +27,44 @@ namespace Tgstation.Server.Host.Database.Migrations
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
- migrationBuilder.DropColumn(
- name: "HeartbeatSeconds",
- table: "DreamDaemonSettings");
+ migrationBuilder.RenameTable(
+ name: "DreamDaemonSettings",
+ newName: "DreamDaemonSettings_down");
+
+ migrationBuilder.CreateTable(
+ name: "DreamDaemonSettings",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ AllowWebClient = table.Column(nullable: false),
+ SecurityLevel = table.Column(nullable: false),
+ PrimaryPort = table.Column(nullable: false),
+ SecondaryPort = table.Column(nullable: false),
+ StartupTimeout = table.Column(nullable: false),
+ AutoStart = table.Column(nullable: false),
+ SoftRestart = table.Column(nullable: false),
+ SoftShutdown = table.Column(nullable: false),
+ ProcessId = table.Column(nullable: true),
+ AccessToken = table.Column(nullable: true),
+ InstanceId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_DreamDaemonSettings", x => x.Id);
+ table.ForeignKey(
+ name: "FK_DreamDaemonSettings_Instances_InstanceId",
+ column: x => x.InstanceId,
+ principalTable: "Instances",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.Sql(
+ $"INSERT INTO DreamDaemonSettings SELECT Id,AllowWebClient,SecurityLevel,PrimaryPort,SecondaryPort,StartupTimeout,AutoStart,SoftRestart,SoftShutdown,ProcessId,AccessToken,InstanceId FROM DreamDaemonSettings_down");
+
+ migrationBuilder.DropTable(
+ name: "DreamDaemonSettings_down");
}
}
}
diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200616180742_SLTopicTimeout.cs b/src/Tgstation.Server.Host/Database/Migrations/20200616180742_SLTopicTimeout.cs
index bca299417f..fcdcdf9500 100644
--- a/src/Tgstation.Server.Host/Database/Migrations/20200616180742_SLTopicTimeout.cs
+++ b/src/Tgstation.Server.Host/Database/Migrations/20200616180742_SLTopicTimeout.cs
@@ -25,9 +25,42 @@ namespace Tgstation.Server.Host.Database.Migrations
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
- migrationBuilder.DropColumn(
- name: "TopicRequestTimeout",
- table: "DreamDaemonSettings");
+
+ migrationBuilder.RenameTable(
+ name: "DreamDaemonSettings",
+ newName: "DreamDaemonSettings_down");
+
+ migrationBuilder.CreateTable(
+ name: "DreamDaemonSettings",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ AllowWebClient = table.Column(nullable: false),
+ SecurityLevel = table.Column(nullable: false),
+ PrimaryPort = table.Column(nullable: false),
+ SecondaryPort = table.Column(nullable: false),
+ StartupTimeout = table.Column(nullable: false),
+ AutoStart = table.Column(nullable: false),
+ InstanceId = table.Column(nullable: false),
+ HeartbeatSeconds = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_DreamDaemonSettings", x => x.Id);
+ table.ForeignKey(
+ name: "FK_DreamDaemonSettings_Instances_InstanceId",
+ column: x => x.InstanceId,
+ principalTable: "Instances",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.Sql(
+ $"INSERT INTO DreamDaemonSettings SELECT Id,AllowWebClient,SecurityLevel,PrimaryPort,SecondaryPort,StartupTimeout,AutoStart,InstanceId,HeartbeatSeconds FROM DreamDaemonSettings_down");
+
+ migrationBuilder.DropTable(
+ name: "DreamDaemonSettings_down");
}
}
}
diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200705163700_SLAllowNullDMApi.cs b/src/Tgstation.Server.Host/Database/Migrations/20200705163700_SLAllowNullDMApi.cs
index 422cdcc5c5..e001cc523f 100644
--- a/src/Tgstation.Server.Host/Database/Migrations/20200705163700_SLAllowNullDMApi.cs
+++ b/src/Tgstation.Server.Host/Database/Migrations/20200705163700_SLAllowNullDMApi.cs
@@ -131,9 +131,37 @@ namespace Tgstation.Server.Host.Database.Migrations
name: "CompileJobs_down",
newName: "CompileJobs");
- migrationBuilder.DropColumn(
- name: "RequireDMApiValidation",
- table: "DreamMakerSettings");
+ migrationBuilder.RenameTable(
+ name: "DreamMakerSettings",
+ newName: "DreamMakerSettings_down");
+
+ migrationBuilder.CreateTable(
+ name: "DreamMakerSettings",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ ProjectName = table.Column(maxLength: 10000, nullable: true),
+ ApiValidationPort = table.Column(nullable: false),
+ ApiValidationSecurityLevel = table.Column(nullable: false),
+ InstanceId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_DreamMakerSettings", x => x.Id);
+ table.ForeignKey(
+ name: "FK_DreamMakerSettings_Instances_InstanceId",
+ column: x => x.InstanceId,
+ principalTable: "Instances",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.Sql(
+ $"INSERT INTO DreamMakerSettings SELECT Id,ProjectName,ApiValidationPort,ApiValidationSecurityLevel,InstanceId FROM DreamMakerSettings_down");
+
+ migrationBuilder.DropTable(
+ name: "DreamMakerSettings_down");
}
}
}
diff --git a/tests/Tgstation.Server.Tests/IntegrationTest.cs b/tests/Tgstation.Server.Tests/IntegrationTest.cs
index 3f02965eca..f2669bcfc9 100644
--- a/tests/Tgstation.Server.Tests/IntegrationTest.cs
+++ b/tests/Tgstation.Server.Tests/IntegrationTest.cs
@@ -1,3 +1,7 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
@@ -15,6 +19,9 @@ using System.Threading.Tasks;
using Tgstation.Server.Api;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Client;
+using Tgstation.Server.Host.Configuration;
+using Tgstation.Server.Host.Database;
+using Tgstation.Server.Host.Database.Migrations;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.System;
using Tgstation.Server.Tests.Instance;
@@ -107,6 +114,54 @@ namespace Tgstation.Server.Tests
} while (true);
}
+#if DEBUG
+ [TestMethod]
+ public async Task TestDownMigrations()
+ {
+ var connectionString = Environment.GetEnvironmentVariable("TGS4_TEST_CONNECTION_STRING");
+
+ if (String.IsNullOrEmpty(connectionString))
+ Assert.Inconclusive("No connection string configured in env var TGS4_TEST_CONNECTION_STRING!");
+
+ var databaseTypeString = Environment.GetEnvironmentVariable("TGS4_TEST_DATABASE_TYPE");
+ if (!Enum.TryParse(databaseTypeString, out var databaseType))
+ Assert.Inconclusive("No/invalid database type configured in env var TGS4_TEST_DATABASE_TYPE!");
+
+ string migrationName = null;
+ DbContext CreateContext()
+ {
+ switch (databaseType)
+ {
+ case DatabaseType.MySql:
+ case DatabaseType.MariaDB:
+ migrationName = nameof(MYInitialCreate);
+ return new MySqlDatabaseContext(Host.Database.Design.DesignTimeDbContextFactoryHelpers.CreateDatabaseContextOptions(databaseType, connectionString));
+ case DatabaseType.PostgresSql:
+ migrationName = nameof(PGCreate);
+ return new PostgresSqlDatabaseContext(Host.Database.Design.DesignTimeDbContextFactoryHelpers.CreateDatabaseContextOptions(databaseType, connectionString));
+ case DatabaseType.SqlServer:
+ migrationName = nameof(MSInitialCreate);
+ return new SqlServerDatabaseContext(Host.Database.Design.DesignTimeDbContextFactoryHelpers.CreateDatabaseContextOptions(databaseType, connectionString));
+ case DatabaseType.Sqlite:
+ migrationName = nameof(SLRebuild);
+ return new SqliteDatabaseContext(Host.Database.Design.DesignTimeDbContextFactoryHelpers.CreateDatabaseContextOptions(databaseType, connectionString));
+ }
+
+ return null;
+ }
+
+ Task Delete(DbContext context) => databaseType == DatabaseType.Sqlite ? Task.CompletedTask : context.Database.EnsureCreatedAsync();
+
+ using var context = CreateContext();
+ await Delete(context);
+ await context.Database.MigrateAsync(default);
+ var dbServiceProvider = ((IInfrastructure)context.Database).Instance;
+ var migrator = dbServiceProvider.GetRequiredService();
+ await migrator.MigrateAsync(migrationName, default);
+ await Delete(context);
+ }
+#endif
+
[TestMethod]
public async Task TestServer()
{