From bb12de8945d015a47e65932edec1b588880a11da Mon Sep 17 00:00:00 2001 From: Andrew Camilleri Date: Thu, 16 Jan 2020 14:05:33 +0100 Subject: [PATCH] Fix Sqlite migration (#1284) --- .../20200110064617_OpenIddictUpdate.cs | 252 +++++++++++++++--- 1 file changed, 218 insertions(+), 34 deletions(-) diff --git a/BTCPayServer.Data/Migrations/20200110064617_OpenIddictUpdate.cs b/BTCPayServer.Data/Migrations/20200110064617_OpenIddictUpdate.cs index 1e10e1a7e..732756590 100644 --- a/BTCPayServer.Data/Migrations/20200110064617_OpenIddictUpdate.cs +++ b/BTCPayServer.Data/Migrations/20200110064617_OpenIddictUpdate.cs @@ -1,4 +1,5 @@ -using BTCPayServer.Data; +using System; +using BTCPayServer.Data; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; @@ -10,21 +11,91 @@ namespace BTCPayServer.Migrations { protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.AlterColumn( - name: "Subject", - table: "OpenIddictTokens", - maxLength: 450, - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 450); + if (!migrationBuilder.IsSqlite()) + { + migrationBuilder.AlterColumn( + name: "Subject", + table: "OpenIddictTokens", + maxLength: 450, + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 450); - migrationBuilder.AlterColumn( - name: "Subject", - table: "OpenIddictAuthorizations", - maxLength: 450, - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 450); + migrationBuilder.AlterColumn( + name: "Subject", + table: "OpenIddictAuthorizations", + maxLength: 450, + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 450); + } + + else + { + ReplaceOldTable(migrationBuilder, s => + { + migrationBuilder.CreateTable( + name: s, + columns: table => new + { + ApplicationId = table.Column(nullable: true, maxLength: null), + AuthorizationId = table.Column(nullable: true, maxLength: null), + ConcurrencyToken = table.Column(maxLength: 50, nullable: true), + CreationDate = table.Column(nullable: true), + ExpirationDate = table.Column(nullable: true), + Id = table.Column(nullable: false, maxLength: null), + Payload = table.Column(nullable: true), + Properties = table.Column(nullable: true), + ReferenceId = table.Column(maxLength: 100, nullable: true), + Status = table.Column(maxLength: 25, nullable: false), + Subject = table.Column(maxLength: 450, nullable: true), + Type = table.Column(maxLength: 25, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OpenIddictTokens", x => x.Id); + table.ForeignKey( + name: "FK_OpenIddictTokens_OpenIddictApplications_ApplicationId", + column: x => x.ApplicationId, + principalTable: "OpenIddictApplications", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_OpenIddictTokens_OpenIddictAuthorizations_AuthorizationId", + column: x => x.AuthorizationId, + principalTable: "OpenIddictAuthorizations", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + }, "OpenIddictTokens"); + + ReplaceOldTable(migrationBuilder, s => + { + migrationBuilder.CreateTable( + name: s, + columns: table => new + { + ApplicationId = table.Column(nullable: true, maxLength: null), + ConcurrencyToken = table.Column(maxLength: 50, nullable: true), + Id = table.Column(nullable: false, maxLength: null), + Properties = table.Column(nullable: true), + Scopes = table.Column(nullable: true), + Status = table.Column(maxLength: 25, nullable: false), + Subject = table.Column(maxLength: 450, nullable: true), + Type = table.Column(maxLength: 25, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OpenIddictAuthorizations", x => x.Id); + table.ForeignKey( + name: "FK_OpenIddictAuthorizations_OpenIddictApplications_ApplicationId", + column: x => x.ApplicationId, + principalTable: "OpenIddictApplications", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + }, "OpenIddictAuthorizations"); + } migrationBuilder.AddColumn( name: "Requirements", @@ -34,27 +105,140 @@ namespace BTCPayServer.Migrations protected override void Down(MigrationBuilder migrationBuilder) { - migrationBuilder.DropColumn( - name: "Requirements", - table: "OpenIddictApplications"); + if (!migrationBuilder.IsSqlite()) + { + migrationBuilder.DropColumn( + name: "Requirements", + table: "OpenIddictApplications"); - migrationBuilder.AlterColumn( - name: "Subject", - table: "OpenIddictTokens", - maxLength: 450, - nullable: false, - oldClrType: typeof(string), - oldMaxLength: 450, - oldNullable: true); + migrationBuilder.AlterColumn( + name: "Subject", + table: "OpenIddictTokens", + maxLength: 450, + nullable: false, + oldClrType: typeof(string), + oldMaxLength: 450, + oldNullable: true); - migrationBuilder.AlterColumn( - name: "Subject", - table: "OpenIddictAuthorizations", - maxLength: 450, - nullable: false, - oldClrType: typeof(string), - oldMaxLength: 450, - oldNullable: true); + migrationBuilder.AlterColumn( + name: "Subject", + table: "OpenIddictAuthorizations", + maxLength: 450, + nullable: false, + oldClrType: typeof(string), + oldMaxLength: 450, + oldNullable: true); + } + else + { + ReplaceOldTable(migrationBuilder, s => + { + migrationBuilder.CreateTable( + name: s, + columns: table => new + { + ApplicationId = table.Column(nullable: true, maxLength: null), + AuthorizationId = table.Column(nullable: true, maxLength: null), + ConcurrencyToken = table.Column(maxLength: 50, nullable: true), + CreationDate = table.Column(nullable: true), + ExpirationDate = table.Column(nullable: true), + Id = table.Column(nullable: false, maxLength: null), + Payload = table.Column(nullable: true), + Properties = table.Column(nullable: true), + ReferenceId = table.Column(maxLength: 100, nullable: true), + Status = table.Column(maxLength: 25, nullable: false), + Subject = table.Column(maxLength: 450, nullable: false), + Type = table.Column(maxLength: 25, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OpenIddictTokens", x => x.Id); + table.ForeignKey( + name: "FK_OpenIddictTokens_OpenIddictApplications_ApplicationId", + column: x => x.ApplicationId, + principalTable: "OpenIddictApplications", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_OpenIddictTokens_OpenIddictAuthorizations_AuthorizationId", + column: x => x.AuthorizationId, + principalTable: "OpenIddictAuthorizations", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + }, "OpenIddictTokens", "WHERE Subject IS NOT NULL"); + + ReplaceOldTable(migrationBuilder, s => + { + migrationBuilder.CreateTable( + name: s, + columns: table => new + { + ApplicationId = table.Column(nullable: true, maxLength: null), + ConcurrencyToken = table.Column(maxLength: 50, nullable: true), + Id = table.Column(nullable: false, maxLength: null), + Properties = table.Column(nullable: true), + Scopes = table.Column(nullable: true), + Status = table.Column(maxLength: 25, nullable: false), + Subject = table.Column(maxLength: 450, nullable: false), + Type = table.Column(maxLength: 25, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OpenIddictAuthorizations", x => x.Id); + table.ForeignKey( + name: "FK_OpenIddictAuthorizations_OpenIddictApplications_ApplicationId", + column: x => x.ApplicationId, + principalTable: "OpenIddictApplications", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + }, "OpenIddictAuthorizations", "WHERE Subject IS NOT NULL"); + + ReplaceOldTable(migrationBuilder, s => + { + migrationBuilder.CreateTable( + name: s, + columns: table => new + { + ClientId = table.Column(maxLength: 100, nullable: false), + ClientSecret = table.Column(nullable: true), + ConcurrencyToken = table.Column(maxLength: 50, nullable: true), + ConsentType = table.Column(nullable: true), + DisplayName = table.Column(nullable: true), + Id = table.Column(nullable: false, maxLength: null), + Permissions = table.Column(nullable: true), + PostLogoutRedirectUris = table.Column(nullable: true), + Properties = table.Column(nullable: true), + RedirectUris = table.Column(nullable: true), + Type = table.Column(maxLength: 25, nullable: false), + ApplicationUserId = table.Column(nullable: true, maxLength: null) + }, + constraints: table => + { + table.PrimaryKey("PK_OpenIddictApplications", x => x.Id); + table.ForeignKey( + name: "FK_OpenIddictApplications_AspNetUsers_ApplicationUserId", + column: x => x.ApplicationUserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + }, "OpenIddictApplications", "", + "ClientId, ClientSecret, ConcurrencyToken, ConsentType, DisplayName, Id, Permissions, PostLogoutRedirectUris, Properties, RedirectUris, Type, ApplicationUserId"); + } + } + + private void ReplaceOldTable(MigrationBuilder migrationBuilder, Action createTable, string tableName, + string whereClause = "", string columns = "*") + { + createTable.Invoke($"New_{tableName}"); + migrationBuilder.Sql( + $"INSERT INTO New_{tableName} {(columns == "*" ? string.Empty : $"({columns})")}SELECT {columns} FROM {tableName} {whereClause};"); + migrationBuilder.Sql("PRAGMA foreign_keys=\"0\"", true); + migrationBuilder.Sql($"DROP TABLE {tableName}", true); + migrationBuilder.Sql($"ALTER TABLE New_{tableName} RENAME TO {tableName}", true); + migrationBuilder.Sql("PRAGMA foreign_keys=\"1\"", true); } } }