diff --git a/Iceshrimp.Backend/Core/Database/DatabaseContext.cs b/Iceshrimp.Backend/Core/Database/DatabaseContext.cs index 95674dd5..43312a56 100644 --- a/Iceshrimp.Backend/Core/Database/DatabaseContext.cs +++ b/Iceshrimp.Backend/Core/Database/DatabaseContext.cs @@ -3,8 +3,10 @@ using EntityFramework.Exceptions.PostgreSQL; using EntityFrameworkCore.Projectables.Infrastructure; using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Database.Tables; +using Iceshrimp.Backend.Core.Extensions; using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; using Npgsql; namespace Iceshrimp.Backend.Core.Database; @@ -1010,4 +1012,21 @@ public class DatabaseContext(DbContextOptions options) public IQueryable NoteDescendants(Note note, int depth, int breadth) => FromExpression(() => NoteDescendants(note.Id, depth, breadth)); +} + +[SuppressMessage("ReSharper", "UnusedType.Global", + Justification = "Constructed using reflection by the dotnet-ef CLI tool")] +public class DesignTimeDatabaseContextFactory : IDesignTimeDbContextFactory { + DatabaseContext IDesignTimeDbContextFactory.CreateDbContext(string[] args) { + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddCustomConfiguration() + .Build(); + + var config = configuration.GetSection("Database").Get(); + var dataSource = DatabaseContext.GetDataSource(config); + var builder = new DbContextOptionsBuilder(); + DatabaseContext.Configure(builder, dataSource); + return new DatabaseContext(builder.Options); + } } \ No newline at end of file diff --git a/Iceshrimp.Backend/Core/Database/Migrations/20240204213755_RemoveHiddenNoteVisibility.cs b/Iceshrimp.Backend/Core/Database/Migrations/20240204213755_RemoveHiddenNoteVisibility.cs index 6dd6bd44..53ddef6f 100644 --- a/Iceshrimp.Backend/Core/Database/Migrations/20240204213755_RemoveHiddenNoteVisibility.cs +++ b/Iceshrimp.Backend/Core/Database/Migrations/20240204213755_RemoveHiddenNoteVisibility.cs @@ -9,6 +9,9 @@ namespace Iceshrimp.Backend.Core.Database.Migrations { /// protected override void Up(MigrationBuilder migrationBuilder) { + Console.WriteLine("Fixing up note visibility enums, please hang tight!"); + Console.WriteLine("This may take a long time (15-30 minutes), especially if your database is unusually large or you're running low end hardware."); + // We want to set all hidden notes to be specified notes that can only be seen by the author before we remove the enum migrationBuilder.Sql(""" UPDATE "note" SET "visibleUserIds" = '{}', "mentions" = '{}', "visibility" = 'specified' WHERE "visibility" = 'hidden'; @@ -27,6 +30,9 @@ namespace Iceshrimp.Backend.Core.Database.Migrations /// protected override void Down(MigrationBuilder migrationBuilder) { + Console.WriteLine("Reverting changes to note visibility enums, please hang tight!"); + Console.WriteLine("This may take a long time (15-30 minutes), especially if your database is unusually large or you're running low end hardware."); + migrationBuilder.Sql(""" ALTER TYPE "public"."note_visibility_enum" RENAME TO "note_visibility_enum_old"; ALTER TYPE "public"."poll_notevisibility_enum" RENAME TO "poll_notevisibility_enum_old"; diff --git a/Iceshrimp.Backend/Core/Database/Migrations/20240210233409_FixNoteMentionsColumnType.cs b/Iceshrimp.Backend/Core/Database/Migrations/20240210233409_FixNoteMentionsColumnType.cs index d534b488..8eb882d2 100644 --- a/Iceshrimp.Backend/Core/Database/Migrations/20240210233409_FixNoteMentionsColumnType.cs +++ b/Iceshrimp.Backend/Core/Database/Migrations/20240210233409_FixNoteMentionsColumnType.cs @@ -12,6 +12,9 @@ namespace Iceshrimp.Backend.Core.Database.Migrations /// protected override void Up(MigrationBuilder migrationBuilder) { + Console.WriteLine("Fixing up note.mentionedRemoteUsers, please hang tight!"); + Console.WriteLine("This may take a long time (15-30 minutes), especially if your database is unusually large or you're running low end hardware."); + migrationBuilder.Sql(""" ALTER TABLE "note" ALTER COLUMN "mentionedRemoteUsers" DROP DEFAULT; ALTER TABLE "note" ALTER COLUMN "mentionedRemoteUsers" TYPE jsonb USING "mentionedRemoteUsers"::jsonb; @@ -22,6 +25,9 @@ namespace Iceshrimp.Backend.Core.Database.Migrations /// protected override void Down(MigrationBuilder migrationBuilder) { + Console.WriteLine("Reverting changes to note.mentionedRemoteUsers, please hang tight!"); + Console.WriteLine("This may take a long time (15-30 minutes), especially if your database is unusually large or you're running low end hardware."); + migrationBuilder.Sql(""" ALTER TABLE "note" ALTER COLUMN "mentionedRemoteUsers" DROP DEFAULT; ALTER TABLE "note" ALTER COLUMN "mentionedRemoteUsers" TYPE text USING "mentionedRemoteUsers"::text; diff --git a/Iceshrimp.Backend/Core/Extensions/ConfigurationBuilderExtensions.cs b/Iceshrimp.Backend/Core/Extensions/ConfigurationBuilderExtensions.cs new file mode 100644 index 00000000..d31774c8 --- /dev/null +++ b/Iceshrimp.Backend/Core/Extensions/ConfigurationBuilderExtensions.cs @@ -0,0 +1,10 @@ +namespace Iceshrimp.Backend.Core.Extensions; + +public static class ConfigurationBuilderExtensions { + public static IConfigurationBuilder AddCustomConfiguration(this IConfigurationBuilder configuration) { + return configuration.AddIniFile(Environment.GetEnvironmentVariable("ICESHRIMP_CONFIG") ?? "configuration.ini", + false, true) + .AddIniFile(Environment.GetEnvironmentVariable("ICESHRIMP_CONFIG_OVERRIDES") ?? "configuration.overrides.ini", + true, true); + } +} \ No newline at end of file diff --git a/Iceshrimp.Backend/Core/Extensions/WebApplicationExtensions.cs b/Iceshrimp.Backend/Core/Extensions/WebApplicationExtensions.cs index d95c11e9..066318bb 100644 --- a/Iceshrimp.Backend/Core/Extensions/WebApplicationExtensions.cs +++ b/Iceshrimp.Backend/Core/Extensions/WebApplicationExtensions.cs @@ -65,7 +65,9 @@ public static class WebApplicationExtensions { if (args.Contains("--migrate") || args.Contains("--migrate-and-start")) { app.Logger.LogInformation("Running migrations..."); + context.Database.SetCommandTimeout(0); await context.Database.MigrateAsync(); + context.Database.SetCommandTimeout(30); if (args.Contains("--migrate")) Environment.Exit(0); } else if ((await context.Database.GetPendingMigrationsAsync()).Any()) { diff --git a/Iceshrimp.Backend/Startup.cs b/Iceshrimp.Backend/Startup.cs index f7148211..97ac1c28 100644 --- a/Iceshrimp.Backend/Startup.cs +++ b/Iceshrimp.Backend/Startup.cs @@ -5,12 +5,7 @@ using Vite.AspNetCore.Extensions; var builder = WebApplication.CreateBuilder(args); builder.Configuration.Sources.Clear(); -builder.Configuration - .AddIniFile(Environment.GetEnvironmentVariable("ICESHRIMP_CONFIG") ?? "configuration.ini", - false, true); -builder.Configuration - .AddIniFile(Environment.GetEnvironmentVariable("ICESHRIMP_CONFIG_OVERRIDES") ?? "configuration.overrides.ini", - true, true); +builder.Configuration.AddCustomConfiguration(); builder.Services.AddControllers(options => { options.ModelBinderProviders.AddHybridBindingProvider(); }) .AddNewtonsoftJson() //TODO: remove once dotNetRdf switches to System.Text.Json (or we switch to LinkedData.NET)