Skip to content

Commit

Permalink
dbUp db migrator
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidEggenberger committed Aug 3, 2024
1 parent 174744f commit e044c1d
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 179 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,25 @@
@inject IModalService modalService

<div class="h-screen w-screen">
<nav class="p-[20px] h-[65px] max-w-[1400px] ml-auto mr-auto w-full pb-0 flex flex-row content-start justify-between items-end">
<nav class="p-5 pb-0 h-[65px] max-w-[1400px] ml-auto mr-auto flex w-full flex-row content-start items-end justify-between">
<div>
<a id="start" href="/">
<h1 class="text-4xl text-sky-700">SaaS template<span class="text-[46px]"></span></h1>
<h1 class="text-primary-900 text-4xl">SaaS template<span class="text-[46px]"></span></h1>
</a>
</div>
<div class="flex flex-row gap-x-3">
<a href="/About">
<span class="text-xl cursor-pointer p-1 hover:bg-white">About</span>
</a>
<div class="gap-x-3 flex flex-row">
<NavLink href="about" ActiveClass="text-primary-900">
<a href="/About">
<span class="p-1 cursor-pointer rounded text-xl hover:bg-primary-100">About</span>
</a>
</NavLink>
<button @onclick="() => OpenSignUpModal()">
<span class="text-xl hover:bg-white border border-1 border-white cursor-pointer p-1 rounded">Sign in</span>
<span class="border-1 border-white p-1 cursor-pointer rounded border text-xl hover:bg-primary-100">Sign in</span>
</button>
</div>
</nav>

<main class="p-[20px] overflow-y-auto h-[calc(100%-65px)] max-w-[1400px] max-h-[900px] ml-auto mr-auto w-full">
<main class="p-5 h-[calc(100%-65px)] max-w-[1400px] max-h-[900px] ml-auto mr-auto w-full overflow-y-auto">
@Body
</main>
</div>
Expand Down
14 changes: 0 additions & 14 deletions Source/Shared/Features/EFCore/DbContextRegistrator.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Shared.Kernel.BuildingBlocks;

namespace Shared.Features.EFCore
{
Expand All @@ -10,18 +8,6 @@ public static class DbContextRegistrator
public static void RegisterDbContext<T>(this IServiceCollection services) where T : DbContext
{
services.AddDbContext<T>();

using (var serviceProvider = services.BuildServiceProvider())
{
if (serviceProvider.GetRequiredService<IExecutionContext>().HostingEnvironment.IsProduction())
{
using (var scope = serviceProvider.CreateScope())
{
var db = scope.ServiceProvider.GetService<T>();
db.Database.Migrate();
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
IF OBJECT_ID(N'[MigrationHistory_TenantIdentity]') IS NULL
BEGIN
CREATE TABLE [MigrationHistory_TenantIdentity] (
[MigrationId] nvarchar(150) NOT NULL,
[ProductVersion] nvarchar(32) NOT NULL,
CONSTRAINT [PK_MigrationHistory_TenantIdentity] PRIMARY KEY ([MigrationId])
);
END;
GO

BEGIN TRANSACTION;
GO

IF SCHEMA_ID(N'Identity') IS NULL EXEC(N'CREATE SCHEMA [Identity];');
GO

CREATE TABLE [Identity].[AspNetRoles] (
[Id] uniqueidentifier NOT NULL,
[Name] nvarchar(256) NULL,
[NormalizedName] nvarchar(256) NULL,
[ConcurrencyStamp] nvarchar(max) NULL,
CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id])
);
GO

CREATE TABLE [Identity].[AspNetUsers] (
[Id] uniqueidentifier NOT NULL,
[PictureUri] nvarchar(max) NULL,
[CountOfOpenTabs] int NOT NULL,
[SelectedTenantId] uniqueidentifier NOT NULL,
[UserName] nvarchar(256) NULL,
[NormalizedUserName] nvarchar(256) NULL,
[Email] nvarchar(256) NULL,
[NormalizedEmail] nvarchar(256) NULL,
[EmailConfirmed] bit NOT NULL,
[PasswordHash] nvarchar(max) NULL,
[SecurityStamp] nvarchar(max) NULL,
[ConcurrencyStamp] nvarchar(max) NULL,
[PhoneNumber] nvarchar(max) NULL,
[PhoneNumberConfirmed] bit NOT NULL,
[TwoFactorEnabled] bit NOT NULL,
[LockoutEnd] datetimeoffset NULL,
[LockoutEnabled] bit NOT NULL,
[AccessFailedCount] int NOT NULL,
CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id])
);
GO

CREATE TABLE [Identity].[TenantSettings] (
[Id] uniqueidentifier NOT NULL,
[IconURI] nvarchar(max) NULL,
[CreatedByUserId] uniqueidentifier NOT NULL,
[IsSoftDeleted] bit NOT NULL,
[RowVersion] varbinary(max) NULL,
[CreatedAt] datetimeoffset NOT NULL,
[LastUpdatedAt] datetimeoffset NOT NULL,
[IsDeleted] bit NOT NULL,
CONSTRAINT [PK_TenantSettings] PRIMARY KEY ([Id])
);
GO

CREATE TABLE [Identity].[TenantStylings] (
[Id] uniqueidentifier NOT NULL,
[CreatedByUserId] uniqueidentifier NOT NULL,
[IsSoftDeleted] bit NOT NULL,
[RowVersion] varbinary(max) NULL,
[CreatedAt] datetimeoffset NOT NULL,
[LastUpdatedAt] datetimeoffset NOT NULL,
[IsDeleted] bit NOT NULL,
CONSTRAINT [PK_TenantStylings] PRIMARY KEY ([Id])
);
GO

CREATE TABLE [Identity].[AspNetRoleClaims] (
[Id] int NOT NULL IDENTITY,
[RoleId] uniqueidentifier NOT NULL,
[ClaimType] nvarchar(max) NULL,
[ClaimValue] nvarchar(max) NULL,
CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY ([Id]),
CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [Identity].[AspNetRoles] ([Id]) ON DELETE CASCADE
);
GO

CREATE TABLE [Identity].[AspNetUserClaims] (
[Id] int NOT NULL IDENTITY,
[UserId] uniqueidentifier NOT NULL,
[ClaimType] nvarchar(max) NULL,
[ClaimValue] nvarchar(max) NULL,
[ApplicationUserId] uniqueidentifier NULL,
CONSTRAINT [PK_AspNetUserClaims] PRIMARY KEY ([Id]),
CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_ApplicationUserId] FOREIGN KEY ([ApplicationUserId]) REFERENCES [Identity].[AspNetUsers] ([Id]),
CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [Identity].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO

CREATE TABLE [Identity].[AspNetUserLogins] (
[LoginProvider] nvarchar(128) NOT NULL,
[ProviderKey] nvarchar(128) NOT NULL,
[ProviderDisplayName] nvarchar(max) NULL,
[UserId] uniqueidentifier NOT NULL,
[ApplicationUserId] uniqueidentifier NULL,
CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY ([LoginProvider], [ProviderKey]),
CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_ApplicationUserId] FOREIGN KEY ([ApplicationUserId]) REFERENCES [Identity].[AspNetUsers] ([Id]),
CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [Identity].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO

CREATE TABLE [Identity].[AspNetUserRoles] (
[UserId] uniqueidentifier NOT NULL,
[RoleId] uniqueidentifier NOT NULL,
CONSTRAINT [PK_AspNetUserRoles] PRIMARY KEY ([UserId], [RoleId]),
CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [Identity].[AspNetRoles] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [Identity].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO

CREATE TABLE [Identity].[AspNetUserTokens] (
[UserId] uniqueidentifier NOT NULL,
[LoginProvider] nvarchar(128) NOT NULL,
[Name] nvarchar(128) NOT NULL,
[Value] nvarchar(max) NULL,
[ApplicationUserId] uniqueidentifier NULL,
CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY ([UserId], [LoginProvider], [Name]),
CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_ApplicationUserId] FOREIGN KEY ([ApplicationUserId]) REFERENCES [Identity].[AspNetUsers] ([Id]),
CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [Identity].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO

CREATE TABLE [Identity].[Tenants] (
[Id] uniqueidentifier NOT NULL,
[TenantId] uniqueidentifier NOT NULL,
[Name] nvarchar(max) NULL,
[StylingId] uniqueidentifier NULL,
[SettingsId] uniqueidentifier NULL,
[SubscriptionPlanType] int NOT NULL,
[CreatedByUserId] uniqueidentifier NOT NULL,
[IsSoftDeleted] bit NOT NULL,
[RowVersion] varbinary(max) NULL,
[CreatedAt] datetimeoffset NOT NULL,
[LastUpdatedAt] datetimeoffset NOT NULL,
[IsDeleted] bit NOT NULL,
CONSTRAINT [PK_Tenants] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Tenants_TenantSettings_SettingsId] FOREIGN KEY ([SettingsId]) REFERENCES [Identity].[TenantSettings] ([Id]),
CONSTRAINT [FK_Tenants_TenantStylings_StylingId] FOREIGN KEY ([StylingId]) REFERENCES [Identity].[TenantStylings] ([Id])
);
GO

CREATE TABLE [Identity].[TenantInvitations] (
[TenantId] uniqueidentifier NOT NULL,
[UserId] uniqueidentifier NOT NULL,
[Role] int NOT NULL,
CONSTRAINT [FK_TenantInvitations_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [Identity].[AspNetUsers] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_TenantInvitations_Tenants_TenantId] FOREIGN KEY ([TenantId]) REFERENCES [Identity].[Tenants] ([Id]) ON DELETE CASCADE
);
GO

CREATE TABLE [Identity].[TenantMeberships] (
[Id] uniqueidentifier NOT NULL,
[UserId] uniqueidentifier NOT NULL,
[TenantId] uniqueidentifier NULL,
[Role] int NOT NULL,
[ApplicationUserId] uniqueidentifier NULL,
[CreatedByUserId] uniqueidentifier NOT NULL,
[IsSoftDeleted] bit NOT NULL,
[RowVersion] varbinary(max) NULL,
[CreatedAt] datetimeoffset NOT NULL,
[LastUpdatedAt] datetimeoffset NOT NULL,
[IsDeleted] bit NOT NULL,
CONSTRAINT [PK_TenantMeberships] PRIMARY KEY ([Id]),
CONSTRAINT [FK_TenantMeberships_AspNetUsers_ApplicationUserId] FOREIGN KEY ([ApplicationUserId]) REFERENCES [Identity].[AspNetUsers] ([Id]),
CONSTRAINT [FK_TenantMeberships_Tenants_TenantId] FOREIGN KEY ([TenantId]) REFERENCES [Identity].[Tenants] ([Id])
);
GO

CREATE INDEX [IX_AspNetRoleClaims_RoleId] ON [Identity].[AspNetRoleClaims] ([RoleId]);
GO

CREATE UNIQUE INDEX [RoleNameIndex] ON [Identity].[AspNetRoles] ([NormalizedName]) WHERE [NormalizedName] IS NOT NULL;
GO

CREATE INDEX [IX_AspNetUserClaims_ApplicationUserId] ON [Identity].[AspNetUserClaims] ([ApplicationUserId]);
GO

CREATE INDEX [IX_AspNetUserClaims_UserId] ON [Identity].[AspNetUserClaims] ([UserId]);
GO

CREATE INDEX [IX_AspNetUserLogins_ApplicationUserId] ON [Identity].[AspNetUserLogins] ([ApplicationUserId]);
GO

CREATE INDEX [IX_AspNetUserLogins_UserId] ON [Identity].[AspNetUserLogins] ([UserId]);
GO

CREATE INDEX [IX_AspNetUserRoles_RoleId] ON [Identity].[AspNetUserRoles] ([RoleId]);
GO

CREATE INDEX [EmailIndex] ON [Identity].[AspNetUsers] ([NormalizedEmail]);
GO

CREATE UNIQUE INDEX [UserNameIndex] ON [Identity].[AspNetUsers] ([NormalizedUserName]) WHERE [NormalizedUserName] IS NOT NULL;
GO

CREATE INDEX [IX_AspNetUserTokens_ApplicationUserId] ON [Identity].[AspNetUserTokens] ([ApplicationUserId]);
GO

CREATE INDEX [IX_TenantInvitations_TenantId] ON [Identity].[TenantInvitations] ([TenantId]);
GO

CREATE INDEX [IX_TenantInvitations_UserId] ON [Identity].[TenantInvitations] ([UserId]);
GO

CREATE INDEX [IX_TenantMeberships_ApplicationUserId] ON [Identity].[TenantMeberships] ([ApplicationUserId]);
GO

CREATE INDEX [IX_TenantMeberships_TenantId] ON [Identity].[TenantMeberships] ([TenantId]);
GO

CREATE INDEX [IX_Tenants_SettingsId] ON [Identity].[Tenants] ([SettingsId]);
GO

CREATE INDEX [IX_Tenants_StylingId] ON [Identity].[Tenants] ([StylingId]);
GO

INSERT INTO [MigrationHistory_TenantIdentity] ([MigrationId], [ProductVersion])
VALUES (N'20240210092230_initial', N'8.0.1');
GO

COMMIT;
GO
31 changes: 31 additions & 0 deletions Source/Shared/Features/EFCore/DbUp/Registrator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using DbUp;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Shared.Features.EFCore.Configuration;
using Shared.Kernel.BuildingBlocks;
using System.Reflection;

namespace Shared.Features.EFCore.DbUp
{
public static class Registrator
{
public static IServiceCollection AddDbUpMigration(this IServiceCollection services)
{
using var serviceProvider = services.BuildServiceProvider();

var isProduction = serviceProvider.GetRequiredService<IExecutionContext>().HostingEnvironment.IsProduction();
var efCoreConfiguration = serviceProvider.GetRequiredService<EFCoreConfiguration>();

var upgrader = DeployChanges.To
.SqlDatabase(isProduction ? efCoreConfiguration.SQLServerConnectionString_Prod : efCoreConfiguration.SQLServerConnectionString_Dev)
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
.JournalToSqlTable("dbo", "MigrationHistory")
.LogToConsole()
.Build();

upgrader.PerformUpgrade();

return services;
}
}
}
2 changes: 2 additions & 0 deletions Source/Shared/Features/EFCore/Registrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Shared.Features.EFCore.Configuration;
using Shared.Features.EFCore.DbUp;
using Shared.Features.Modules.Configuration;

namespace Shared.Features.EFCore
Expand All @@ -12,6 +13,7 @@ public static IServiceCollection AddEFCore(this IServiceCollection services, ICo
{
services.RegisterModuleConfiguration<EFCoreConfiguration, EFCoreConfigurationValidator>(configuration);
services.AddScoped<TransactionScopeMiddleware>();
services.AddDbUpMigration();

return services;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Shared/Features/Registrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ public static IServiceCollection AddSharedFeatures(this IServiceCollection servi
var serviceProvider = services.BuildServiceProvider();
var configuration = serviceProvider.GetRequiredService<IConfiguration>();

services.AddServerExecutionContext();
services.AddMessaging();
services.AddEFCore(configuration);
services.AddEmailSender(configuration);
services.Add_SignalR();
services.AddServerExecutionContext();

return services;
}
Expand Down
12 changes: 12 additions & 0 deletions Source/Shared/Features/Shared.Features.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,23 @@
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<None Remove="EFCore\DbUp\Migrations\0001_TenantIdentity_Initial.sql" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="EFCore\DbUp\Migrations\0001_TenantIdentity_Initial.sql">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="dbup-core" Version="5.0.87" />
<PackageReference Include="dbup-sqlserver" Version="5.0.41" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.1" />
Expand Down
2 changes: 1 addition & 1 deletion Source/Web/Server/Pages/_Host.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<link rel="stylesheet" href="css/fonts.css" />
<link rel="stylesheet" href=@($"{TailwindSourceConstant.TailwindOutputPath}") />
</head>
<body class="h-screen bg-gradient-to-b from-white to-blue-100 grid place-content-center">
<body class="from-white to-primary-100 grid h-screen place-content-center bg-gradient-to-b">
@if (User.Identity.IsAuthenticated)
{
<component type="typeof(ClientApp)" render-mode="WebAssembly" />
Expand Down
2 changes: 1 addition & 1 deletion Source/Web/Server/Web.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<ItemGroup>
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.2.2" />
<PackageReference Include="Azure.Identity" Version="1.9.0" />
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1">
Expand Down
Loading

0 comments on commit e044c1d

Please sign in to comment.