diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj
index f6ce11c8..86894b7a 100644
--- a/Oqtane.Client/Oqtane.Client.csproj
+++ b/Oqtane.Client/Oqtane.Client.csproj
@@ -28,11 +28,11 @@
-
-
-
+
+
+
-
+
diff --git a/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs
index e34d1563..4904d0d3 100644
--- a/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs
+++ b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs
@@ -8,6 +8,7 @@ namespace Oqtane.Extensions
public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, string connectionString)
{
optionsBuilder.UseSqlServer(connectionString);
+ //optionsBuilder.UseSqlite("Data Source=Oqtane.db");
return optionsBuilder;
}
diff --git a/Oqtane.Server/Migrations/01000000_InitializeMaster.cs b/Oqtane.Server/Migrations/01000000_InitializeMaster.cs
new file mode 100644
index 00000000..0465e058
--- /dev/null
+++ b/Oqtane.Server/Migrations/01000000_InitializeMaster.cs
@@ -0,0 +1,60 @@
+using System;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Migrations.Extensions;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(MasterDBContext))]
+ [Migration("Master.01.00.00.00")]
+ public class InitializeMaster : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Create Tenant table
+ var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
+ tenantEntityBuilder.Create();
+
+ //Create Alias table
+ var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
+ aliasEntityBuilder.Create();
+
+ //Create ModuleDefinitions Table
+ var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder);
+ moduleDefinitionsEntityBuilder.Create();
+
+ //Create Job Table
+ var jobEntityBuilder = new JobEntityBuilder(migrationBuilder);
+ jobEntityBuilder.Create();
+
+ //Create JobLog Table
+ var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder);
+ jobLogEntityBuilder.Create();
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Drop Alias table
+ var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
+ aliasEntityBuilder.Drop();
+
+ //Drop JobLog Table
+ var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder);
+ jobLogEntityBuilder.Drop();
+
+ //Drop Tenant table
+ var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
+ tenantEntityBuilder.Drop();
+
+ //Drop ModuleDefinitions Table
+ var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder);
+ moduleDefinitionsEntityBuilder.Drop();
+
+ //Drop Job Table
+ var jobEntityBuilder = new JobEntityBuilder(migrationBuilder);
+ jobEntityBuilder.Drop();
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/01000000_InitializeTenant.cs b/Oqtane.Server/Migrations/01000000_InitializeTenant.cs
new file mode 100644
index 00000000..d977e508
--- /dev/null
+++ b/Oqtane.Server/Migrations/01000000_InitializeTenant.cs
@@ -0,0 +1,157 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.01.00.00.00")]
+ public class InitializeTenant : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Create Site table
+ var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder);
+ siteEntityBuilder.Create();
+
+ //Create Page table
+ var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
+ pageEntityBuilder.Create();
+ pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true);
+
+ //Create Module table
+ var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder);
+ moduleEntityBuilder.Create();
+
+ //Create PageModule table
+ var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder);
+ pageModuleEntityBuilder.Create();
+
+ //Create User table
+ var userEntityBuilder = new UserEntityBuilder(migrationBuilder);
+ userEntityBuilder.Create();
+ userEntityBuilder.AddIndex("IX_User", "Username", true);
+
+ //Create Role table
+ var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder);
+ roleEntityBuilder.Create();
+
+ //Create UserRole table
+ var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder);
+ userRoleEntityBuilder.Create();
+ userRoleEntityBuilder.AddIndex("IX_UserRole", new [] {"RoleId", "UserId"}, true);
+
+ //Create Permission table
+ var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder);
+ permissionEntityBuilder.Create();
+ permissionEntityBuilder.AddIndex("IX_Permission", new [] {"SiteId", "EntityName", "EntityId", "PermissionName", "RoleId", "UserId"}, true);
+
+ //Create Setting table
+ var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder);
+ settingEntityBuilder.Create();
+ settingEntityBuilder.AddIndex("IX_Setting", new [] {"EntityName", "EntityId", "SettingName"}, true);
+
+ //Create Profile table
+ var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder);
+ profileEntityBuilder.Create();
+
+ //Create Log table
+ var logEntityBuilder = new LogEntityBuilder(migrationBuilder);
+ logEntityBuilder.Create();
+
+ //Create Notification table
+ var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
+ notificationEntityBuilder.Create();
+
+ //Create Folder table
+ var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder);
+ folderEntityBuilder.Create();
+ folderEntityBuilder.AddIndex("IX_Folder", new [] {"SiteId", "Path"}, true);
+
+ //Create File table
+ var fileEntityBuilder = new FileEntityBuilder(migrationBuilder);
+ fileEntityBuilder.Create();
+
+ //Create AspNetUsers table
+ var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder);
+ aspNetUsersEntityBuilder.Create();
+ aspNetUsersEntityBuilder.AddIndex("EmailIndex", "NormalizedEmail", true);
+ aspNetUsersEntityBuilder.AddIndex("UserNameIndex", "NormalizedUserName", true);
+
+ //Create AspNetUserClaims table
+ var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder);
+ aspNetUserClaimsEntityBuilder.Create();
+ aspNetUserClaimsEntityBuilder.AddIndex("IX_AspNetUserClaims_UserId", "UserId", true);
+
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Drop AspNetUserClaims table
+ var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder);
+ aspNetUserClaimsEntityBuilder.Drop();
+
+ //Drop AspNetUsers table
+ var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder);
+ aspNetUsersEntityBuilder.Drop();
+
+ //Drop File table
+ var fileEntityBuilder = new FileEntityBuilder(migrationBuilder);
+ fileEntityBuilder.Drop();
+
+ //Drop Folder table
+ var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder);
+ folderEntityBuilder.Drop();
+
+ //Drop Notification table
+ var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
+ notificationEntityBuilder.Drop();
+
+ //Drop Log table
+ var logEntityBuilder = new LogEntityBuilder(migrationBuilder);
+ logEntityBuilder.Drop();
+
+ //Drop Profile table
+ var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder);
+ profileEntityBuilder.Drop();
+
+ //Drop Setting table
+ var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder);
+ settingEntityBuilder.Drop();
+
+ //Drop Permission table
+ var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder);
+ permissionEntityBuilder.Drop();
+
+ //Drop UserRole table
+ var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder);
+ userRoleEntityBuilder.Drop();
+
+ //Drop Role table
+ var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder);
+ roleEntityBuilder.Drop();
+
+ //Drop User table
+ var userEntityBuilder = new UserEntityBuilder(migrationBuilder);
+ userEntityBuilder.Drop();
+
+ //Drop PageModule table
+ var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder);
+ pageModuleEntityBuilder.Drop();
+
+ //Drop Module table
+ var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder);
+ moduleEntityBuilder.Drop();
+
+ //Drop Page table
+ var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
+ pageEntityBuilder.Drop();
+
+ //Drop Site table
+ var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder);
+ siteEntityBuilder.Drop();
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInMaster.cs b/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInMaster.cs
new file mode 100644
index 00000000..7257bbb1
--- /dev/null
+++ b/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInMaster.cs
@@ -0,0 +1,50 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(MasterDBContext))]
+ [Migration("Master.01.00.01.00")]
+ public class AddAdditionalIndexesInMaster : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Update Tenant table
+ var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
+ tenantEntityBuilder.AddIndex("IX_Tenant", "Name");
+
+ //Update Alias table
+ var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
+ aliasEntityBuilder.AddIndex("IX_Alias", "Name");
+
+ //Update ModuleDefinitions Table
+ var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder);
+ moduleDefinitionsEntityBuilder.AddIndex("IX_ModuleDefinition", "ModuleDefinitionName");
+
+ //Update Job Table
+ var jobEntityBuilder = new JobEntityBuilder(migrationBuilder);
+ jobEntityBuilder.AddIndex("IX_Job", "JobType");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Update Tenant table
+ var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
+ tenantEntityBuilder.DropIndex("IX_Tenant");
+
+ //Update Alias table
+ var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
+ aliasEntityBuilder.DropIndex("IX_Alias");
+
+ //Update ModuleDefinitions Table
+ var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder);
+ moduleDefinitionsEntityBuilder.DropIndex("IX_ModuleDefinition");
+
+ //Update Job Table
+ var jobEntityBuilder = new JobEntityBuilder(migrationBuilder);
+ jobEntityBuilder.DropIndex("IX_Job");
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInTenant.cs b/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInTenant.cs
new file mode 100644
index 00000000..158c8b0f
--- /dev/null
+++ b/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInTenant.cs
@@ -0,0 +1,64 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Migrations.Extensions;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.01.00.01.00")]
+ public class AddAdditionalIndexesInTenant : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Create Index on Site
+ var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder);
+ siteEntityBuilder.AddIndex("IX_Site", new [] {"TenantId", "Name"}, true);
+
+ //Create Index on Role table
+ var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder);
+ roleEntityBuilder.AddIndex("IX_Role", new [] {"SiteId", "Name"}, true);
+
+ //Create Index on Profile table
+ var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder);
+ profileEntityBuilder.AddIndex("IX_Profile", new [] {"SiteId", "Name"}, true);
+
+ //Create Index on File table
+ var fileEntityBuilder = new FileEntityBuilder(migrationBuilder);
+ fileEntityBuilder.AddIndex("IX_File", new [] {"FolderId", "Name"}, true);
+
+ //Add Columns to Notification table
+ var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
+ notificationEntityBuilder.AddStringColumn("FromDisplayName", 50, true);
+ notificationEntityBuilder.AddStringColumn("FromEmail", 256, true);
+ notificationEntityBuilder.AddStringColumn("ToDisplayName", 50, true);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Drop Index on Site table
+ var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder);
+ siteEntityBuilder.DropIndex("IX_Site");
+
+ //Drop Index on Role table
+ var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder);
+ roleEntityBuilder.DropIndex("IX_Role");
+
+ //Drop Index on Profile table
+ var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder);
+ profileEntityBuilder.DropIndex("IX_Profile");
+
+ //Drop Index on File table
+ var fileEntityBuilder = new FileEntityBuilder(migrationBuilder);
+ fileEntityBuilder.DropIndex("IX_File");
+
+ //Drop Columns from Notification table
+ var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
+ notificationEntityBuilder.DropColumn("FromDisplayName");
+ notificationEntityBuilder.DropColumn("FromEmail");
+ notificationEntityBuilder.DropColumn("ToDisplayName");
+ }
+
+ }
+}
diff --git a/Oqtane.Server/Migrations/01000101_AddAdditionColumnToNotifications.cs b/Oqtane.Server/Migrations/01000101_AddAdditionColumnToNotifications.cs
new file mode 100644
index 00000000..7d01d0b0
--- /dev/null
+++ b/Oqtane.Server/Migrations/01000101_AddAdditionColumnToNotifications.cs
@@ -0,0 +1,33 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.01.00.01.01")]
+ public class AddAdditionColumnToNotifications : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Add Column to Notification table
+ var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
+ notificationEntityBuilder.AddDateTimeColumn("SendOn", true);
+
+ migrationBuilder.Sql(
+ @"
+ UPDATE Notification
+ SET SendOn = CreatedOn
+ WHERE SendOn IS NULL;
+ ");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Drop Column from Notification table
+ var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
+ notificationEntityBuilder.DropColumn("SendOn");
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/01000201_DropColumnFromPage.cs b/Oqtane.Server/Migrations/01000201_DropColumnFromPage.cs
new file mode 100644
index 00000000..516aae4d
--- /dev/null
+++ b/Oqtane.Server/Migrations/01000201_DropColumnFromPage.cs
@@ -0,0 +1,29 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.01.00.02.01")]
+ public class DropColumnFromPage : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Drop Column from Page table
+ if (migrationBuilder.ActiveProvider != "Microsoft.EntityFrameworkCore.Sqlite")
+ {
+ var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
+ pageEntityBuilder.DropColumn("EditMode");
+ }
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Add Column to Page table
+ var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
+ pageEntityBuilder.AddBooleanColumn("EditMode");
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/02000001_AddColumnToProfileAndUpdatePage.cs b/Oqtane.Server/Migrations/02000001_AddColumnToProfileAndUpdatePage.cs
new file mode 100644
index 00000000..79555898
--- /dev/null
+++ b/Oqtane.Server/Migrations/02000001_AddColumnToProfileAndUpdatePage.cs
@@ -0,0 +1,51 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.02.00.00.01")]
+ public class AddColumnToProfileAndUpdatePage : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Add Column to Profile table
+ var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder);
+ profileEntityBuilder.AddStringColumn("Options", 2000, true);
+
+ ///Update new field
+ migrationBuilder.Sql(
+ @"
+ UPDATE Profile
+ SET Options = ''
+ ");
+
+ //Alter Column in Page table
+ if (migrationBuilder.ActiveProvider != "Microsoft.EntityFrameworkCore.Sqlite")
+ {
+ var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
+ pageEntityBuilder.DropIndex("IX_Page");
+ pageEntityBuilder.AlterStringColumn("Path", 256);
+ pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true);
+ }
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Drop Column from Profile table
+ var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder);
+ profileEntityBuilder.DropColumn("Options");
+
+ //Alter Column in Page table
+ if (migrationBuilder.ActiveProvider != "Microsoft.EntityFrameworkCore.Sqlite")
+ {
+ var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
+ pageEntityBuilder.DropIndex("IX_Page");
+ pageEntityBuilder.AlterStringColumn("Path", 50);
+ pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true);
+ }
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/02000101_UpdateIconColumnInPage.cs b/Oqtane.Server/Migrations/02000101_UpdateIconColumnInPage.cs
new file mode 100644
index 00000000..d62220ea
--- /dev/null
+++ b/Oqtane.Server/Migrations/02000101_UpdateIconColumnInPage.cs
@@ -0,0 +1,21 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.02.00.01.01")]
+ public class UpdateIconColumnInPage : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ ///Update Icon Field in Page
+ migrationBuilder.Sql(
+ @"
+ UPDATE [Page]
+ SET Icon = IIF(Icon <> '', 'oi oi-' + Icon, '');
+ ");
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/02000102_AddLanguageTable.cs b/Oqtane.Server/Migrations/02000102_AddLanguageTable.cs
new file mode 100644
index 00000000..21514c31
--- /dev/null
+++ b/Oqtane.Server/Migrations/02000102_AddLanguageTable.cs
@@ -0,0 +1,26 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.02.00.01.02")]
+ public class AddLanguageTable : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Create Language table
+ var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder);
+ languageEntityBuilder.Create();
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Drop Language table
+ var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder);
+ languageEntityBuilder.Drop();
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/02000103_UpdatePageAndAddColumnToSite.cs b/Oqtane.Server/Migrations/02000103_UpdatePageAndAddColumnToSite.cs
new file mode 100644
index 00000000..3b098e3a
--- /dev/null
+++ b/Oqtane.Server/Migrations/02000103_UpdatePageAndAddColumnToSite.cs
@@ -0,0 +1,41 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.02.00.01.03")]
+ public class UpdatePageAndAddColumnToSite : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Add Column to Site table
+ var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder);
+ siteEntityBuilder.AddStringColumn("AdminContainerType", 200, true);
+
+ //Update new column
+ migrationBuilder.Sql(
+ @"
+ UPDATE Site
+ SET AdminContainerType = ''
+ ");
+
+ //Delete records from Page
+ migrationBuilder.Sql(
+ @"
+ DELETE FROM [Page]
+ WHERE Path = 'admin/tenants';
+ ");
+
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Drop Column from Site table
+ var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder);
+ siteEntityBuilder.DropColumn("AdminContainerType");
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/02010000_AddIndexesForForeignKeyInMaster.cs b/Oqtane.Server/Migrations/02010000_AddIndexesForForeignKeyInMaster.cs
new file mode 100644
index 00000000..bbbeb06c
--- /dev/null
+++ b/Oqtane.Server/Migrations/02010000_AddIndexesForForeignKeyInMaster.cs
@@ -0,0 +1,34 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+
+namespace Oqtane.Migrations
+{
+ [DbContext(typeof(MasterDBContext))]
+ [Migration("Master.02.01.00.00")]
+ public class AddIndexesForForeignKeyInMaster : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ //Update JobLog table
+ var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder);
+ jobLogEntityBuilder.AddIndex("IX_JobLog_JobId", "JobId");
+
+ //Update Alias table
+ var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
+ aliasEntityBuilder.AddIndex("IX_Alias_TenantId", "TenantId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ //Update JobLog table
+ var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder);
+ jobLogEntityBuilder.DropIndex("IX_JobLog_JobId");
+
+ //Update Alias table
+ var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
+ aliasEntityBuilder.DropIndex("IX_Alias_TenantId");
+ }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/AliasEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/AliasEntityBuilder.cs
new file mode 100644
index 00000000..fad6bd1a
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/AliasEntityBuilder.cs
@@ -0,0 +1,44 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class AliasEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Alias";
+ private readonly PrimaryKey _primaryKey = new("PK_Alias", x => x.AliasId);
+ private readonly ForeignKey _tenantForeignKey = new("FK_Alias_Tenant", x => x.TenantId, "Tenant", "TenantId", ReferentialAction.Cascade);
+
+ public AliasEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_tenantForeignKey);
+ }
+
+ protected override AliasEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ AliasId = table.AddAutoIncrementColumn("AliasId");
+ Name = table.AddStringColumn("Name", 200);
+ TenantId = table.AddIntegerColumn("TenantId");
+ SiteId = table.AddIntegerColumn("SiteId");
+
+ AddAuditableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder AliasId { get; private set; }
+
+ public OperationBuilder Name { get; private set; }
+
+ public OperationBuilder SiteId { get; private set; }
+
+ public OperationBuilder TenantId { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/AspNetUserClaimsEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/AspNetUserClaimsEntityBuilder.cs
new file mode 100644
index 00000000..a99c9067
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/AspNetUserClaimsEntityBuilder.cs
@@ -0,0 +1,42 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class AspNetUserClaimsEntityBuilder : BaseEntityBuilder
+ {
+ private const string _entityTableName = "AspNetUserClaims";
+ private readonly PrimaryKey _primaryKey = new("PK_AspNetUserClaims", x => x.Id);
+ private readonly ForeignKey _aspNetUsersForeignKey = new("FK_AspNetUserClaims_AspNetUsers_UserId", x => x.UserId, "AspNetUsers", "Id", ReferentialAction.Cascade);
+
+ public AspNetUserClaimsEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_aspNetUsersForeignKey);
+ }
+
+ protected override AspNetUserClaimsEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ Id = table.AddAutoIncrementColumn("Id");
+ UserId = table.AddStringColumn("UserId", 450);
+ ClaimType = table.AddMaxStringColumn("ClaimType", true);
+ ClaimValue = table.AddMaxStringColumn("ClaimValue", true);
+
+ return this;
+ }
+
+ public OperationBuilder Id { get; set; }
+
+ public OperationBuilder UserId { get; set; }
+
+ public OperationBuilder ClaimType { get; set; }
+
+ public OperationBuilder ClaimValue { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/AspNetUsersEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/AspNetUsersEntityBuilder.cs
new file mode 100644
index 00000000..e6ac3b45
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/AspNetUsersEntityBuilder.cs
@@ -0,0 +1,73 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class AspNetUsersEntityBuilder : BaseEntityBuilder
+ {
+ private const string _entityTableName = "AspNetUsers";
+ private readonly PrimaryKey _primaryKey = new("PK_AspNetUsers", x => x.Id);
+
+ public AspNetUsersEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ }
+
+ protected override AspNetUsersEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ Id = table.AddStringColumn("Id", 450);
+ UserName = table.AddStringColumn("Username", 256, true);
+ NormalizedUserName = table.AddStringColumn("NormalizedUserName", 256, true);
+ Email = table.AddStringColumn("Email", 256, true);
+ NormalizedEmail = table.AddStringColumn("NormalizedEmail", 256, true);
+ EmailConfirmed = table.AddBooleanColumn("EmailConfirmed");
+ PasswordHash = table.AddMaxStringColumn("PasswordHash", true);
+ SecurityStamp = table.AddMaxStringColumn("SecurityStamp", true);
+ ConcurrencyStamp = table.AddMaxStringColumn("ConcurrencyStamp", true);
+ PhoneNumber = table.AddMaxStringColumn("PhoneNumber", true);
+ PhoneNumberConfirmed = table.AddBooleanColumn("PhoneNumberConfirmed");
+ TwoFactorEnabled = table.AddBooleanColumn("TwoFactorEnabled");
+ LockoutEnd = table.AddDateTimeOffsetColumn("LockoutEnd", true);
+ LockoutEnabled = table.AddBooleanColumn("LockoutEnabled");
+ AccessFailedCount = table.AddIntegerColumn("AccessFailedCount");
+
+ return this;
+ }
+
+ public OperationBuilder Id { get; set; }
+
+ public OperationBuilder UserName { get; set; }
+
+ public OperationBuilder NormalizedUserName { get; set; }
+
+ public OperationBuilder Email { get; set; }
+
+ public OperationBuilder NormalizedEmail { get; set; }
+
+ public OperationBuilder EmailConfirmed { get; set; }
+
+ public OperationBuilder PasswordHash { get; set; }
+
+ public OperationBuilder SecurityStamp { get; set; }
+
+ public OperationBuilder ConcurrencyStamp { get; set; }
+
+ public OperationBuilder PhoneNumber { get; set; }
+
+ public OperationBuilder PhoneNumberConfirmed { get; set; }
+
+ public OperationBuilder TwoFactorEnabled { get; set; }
+
+ public OperationBuilder LockoutEnd { get; set; }
+
+ public OperationBuilder LockoutEnabled { get; set; }
+
+ public OperationBuilder AccessFailedCount { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/AuditableBaseEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/AuditableBaseEntityBuilder.cs
new file mode 100644
index 00000000..9f805d6e
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/AuditableBaseEntityBuilder.cs
@@ -0,0 +1,34 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+// ReSharper disable MemberCanBePrivate.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public abstract class AuditableBaseEntityBuilder : BaseEntityBuilder where TEntityBuilder : BaseEntityBuilder
+ {
+ protected AuditableBaseEntityBuilder(MigrationBuilder migrationBuilder) : base (migrationBuilder)
+ {
+ }
+
+ protected void AddAuditableColumns(ColumnsBuilder table)
+ {
+ CreatedBy = table.AddStringColumn("CreatedBy", 256);
+ CreatedOn = table.AddDateTimeColumn("CreatedOn");
+ ModifiedBy = table.AddStringColumn("ModifiedBy", 256);
+ ModifiedOn = table.AddDateTimeColumn("ModifiedOn");
+ }
+
+
+ public OperationBuilder CreatedBy { get; private set; }
+
+ public OperationBuilder CreatedOn { get; private set; }
+
+ public OperationBuilder ModifiedBy { get; private set; }
+
+ public OperationBuilder ModifiedOn { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/BaseEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/BaseEntityBuilder.cs
new file mode 100644
index 00000000..d58a88a2
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/BaseEntityBuilder.cs
@@ -0,0 +1,118 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public abstract class BaseEntityBuilder where TEntityBuilder : BaseEntityBuilder
+ {
+ private readonly MigrationBuilder _migrationBuilder;
+
+ protected BaseEntityBuilder(MigrationBuilder migrationBuilder)
+ {
+ _migrationBuilder = migrationBuilder;
+ ForeignKeys = new List>();
+ }
+
+ private void AddKeys(CreateTableBuilder table)
+ {
+ table.AddPrimaryKey(PrimaryKey);
+ foreach (var foreignKey in ForeignKeys)
+ {
+ table.AddForeignKey(foreignKey);
+ }
+
+ }
+
+ protected abstract TEntityBuilder BuildTable(ColumnsBuilder table);
+
+ protected string EntityTableName { get; init; }
+
+ protected PrimaryKey PrimaryKey { get; init; }
+
+ protected List> ForeignKeys { get; }
+
+ public void AddBooleanColumn(string name)
+ {
+ _migrationBuilder.AddColumn(name, EntityTableName);
+ }
+
+ public void AddDateTimeColumn(string name, bool nullable = false)
+ {
+ _migrationBuilder.AddColumn(name, EntityTableName, nullable: nullable);
+ }
+
+ ///
+ /// Creates a Migration to add an Index to the Entity (table)
+ ///
+ /// The name of the Index to create
+ /// The name of the column to add to the index
+ /// A flag that determines if the Index should be Unique
+ public virtual void AddIndex(string indexName, string columnName, bool isUnique = false)
+ {
+ _migrationBuilder.CreateIndex(
+ name: indexName,
+ table: EntityTableName,
+ column: columnName,
+ unique: isUnique);
+ }
+
+ ///
+ /// Creates a Migration to add an Index to the Entity (table)
+ ///
+ /// The name of the Index to create
+ /// The names of the columns to add to the index
+ /// A flag that determines if the Index should be Unique
+ public virtual void AddIndex(string indexName, string[] columnNames, bool isUnique = false)
+ {
+ _migrationBuilder.CreateIndex(
+ name: indexName,
+ table: EntityTableName,
+ columns: columnNames,
+ unique: isUnique);
+ }
+
+ public void AddStringColumn(string name, int length, bool nullable = false)
+ {
+ _migrationBuilder.AddColumn(name, EntityTableName, maxLength: length, nullable: nullable);
+ }
+
+ public void AlterStringColumn(string name, int length, bool nullable = false)
+ {
+ _migrationBuilder.AlterColumn(name, EntityTableName, maxLength: length, nullable: nullable);
+ }
+
+ ///
+ /// Creates a Migration to Create the Entity (table)
+ ///
+ public void Create()
+ {
+ _migrationBuilder.CreateTable(EntityTableName, BuildTable, null, AddKeys);
+ }
+
+ ///
+ /// Creates a Migration to Drop the Entity (table)
+ ///
+ public void Drop()
+ {
+ _migrationBuilder.DropTable(EntityTableName);
+ }
+
+ public void DropColumn(string name)
+ {
+ _migrationBuilder.DropColumn(name, EntityTableName);
+ }
+
+ ///
+ /// Creates a Migration to drop an Index from the Entity (table)
+ ///
+ /// The name of the Index to drop
+ public virtual void DropIndex(string indexName)
+ {
+ _migrationBuilder.DropIndex(indexName, EntityTableName);
+ }
+ }
+}
+
diff --git a/Oqtane.Server/Migrations/EntityBuilders/DeletableAuditableBaseEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/DeletableAuditableBaseEntityBuilder.cs
new file mode 100644
index 00000000..81cdd9e6
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/DeletableAuditableBaseEntityBuilder.cs
@@ -0,0 +1,30 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+// ReSharper disable MemberCanBePrivate.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public abstract class DeletableAuditableBaseEntityBuilder : AuditableBaseEntityBuilder where TEntityBuilder : BaseEntityBuilder
+ {
+ protected DeletableAuditableBaseEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ }
+
+ protected void AddDeletableColumns(ColumnsBuilder table)
+ {
+ DeletedBy = table.AddStringColumn("DeletedBy", 256, true);
+ DeletedOn = table.AddDateTimeColumn("DeletedOn", true);
+ IsDeleted = table.AddBooleanColumn("IsDeleted");
+ }
+
+ public OperationBuilder DeletedBy { get; private set; }
+
+ public OperationBuilder DeletedOn { get; private set; }
+
+ public OperationBuilder IsDeleted { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/DeletableBaseEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/DeletableBaseEntityBuilder.cs
new file mode 100644
index 00000000..c9bba190
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/DeletableBaseEntityBuilder.cs
@@ -0,0 +1,30 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+// ReSharper disable MemberCanBePrivate.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public abstract class DeletableBaseEntityBuilder : BaseEntityBuilder where TEntityBuilder : BaseEntityBuilder
+ {
+ protected DeletableBaseEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ }
+
+ protected void AddDeletableColumns(ColumnsBuilder table)
+ {
+ DeletedBy = table.AddStringColumn("DeletedBy", 256, true);
+ DeletedOn = table.AddDateTimeColumn("DeletedOn", true);
+ IsDeleted = table.AddBooleanColumn("IsDeleted");
+ }
+
+ public OperationBuilder DeletedBy { get; private set; }
+
+ public OperationBuilder DeletedOn { get; private set; }
+
+ public OperationBuilder IsDeleted { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/FileEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/FileEntityBuilder.cs
new file mode 100644
index 00000000..695935a1
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/FileEntityBuilder.cs
@@ -0,0 +1,54 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class FileEntityBuilder : DeletableAuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "File";
+ private readonly PrimaryKey _primaryKey = new("PK_File", x => x.FileId);
+ private readonly ForeignKey _folderForeignKey = new("FK_File_Folder", x => x.FolderId, "Folder", "FolderId", ReferentialAction.Cascade);
+
+ public FileEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_folderForeignKey);
+ }
+
+ protected override FileEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ FileId = table.AddAutoIncrementColumn("FileId");
+ FolderId = table.AddIntegerColumn("FolderId");
+ Name = table.AddStringColumn("Name", 50);
+ Extension = table.AddStringColumn("Extension", 50);
+ Size = table.AddIntegerColumn("Size");
+ ImageHeight = table.AddIntegerColumn("ImageHeight");
+ ImageWidth = table.AddIntegerColumn("ImageWidth");
+
+ AddAuditableColumns(table);
+ AddDeletableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder FileId { get; set; }
+
+ public OperationBuilder FolderId { get; set; }
+
+ public OperationBuilder Name { get; set; }
+
+ public OperationBuilder Extension { get; set; }
+
+ public OperationBuilder Size { get; set; }
+
+ public OperationBuilder ImageHeight { get; set; }
+
+ public OperationBuilder ImageWidth { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/FolderEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/FolderEntityBuilder.cs
new file mode 100644
index 00000000..d7d5f63d
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/FolderEntityBuilder.cs
@@ -0,0 +1,54 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class FolderEntityBuilder : DeletableAuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Folder";
+ private readonly PrimaryKey _primaryKey = new("PK_Folder", x => x.FolderId);
+ private readonly ForeignKey _siteForeignKey = new("FK_Folder_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
+
+ public FolderEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_siteForeignKey);
+ }
+
+ protected override FolderEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ FolderId = table.AddAutoIncrementColumn("FolderId");
+ SiteId = table.AddIntegerColumn("SiteId");
+ ParentId = table.AddIntegerColumn("ParentId", true);
+ Name = table.AddStringColumn("Name", 50);
+ Path = table.AddStringColumn("Path", 50);
+ Order = table.AddIntegerColumn("Order");
+ IsSystem = table.AddBooleanColumn("IsSystem");
+
+ AddAuditableColumns(table);
+ AddDeletableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder FolderId { get; set; }
+
+ public OperationBuilder SiteId { get; set; }
+
+ public OperationBuilder ParentId { get; set; }
+
+ public OperationBuilder Name { get; set; }
+
+ public OperationBuilder Path { get; set; }
+
+ public OperationBuilder Order { get; set; }
+
+ public OperationBuilder IsSystem { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/JobEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/JobEntityBuilder.cs
new file mode 100644
index 00000000..1cdda817
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/JobEntityBuilder.cs
@@ -0,0 +1,66 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class JobEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Job";
+ private readonly PrimaryKey _primaryKey = new("PK_Job", x => x.JobId);
+
+ public JobEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ }
+
+ protected override JobEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ JobId = table.AddAutoIncrementColumn("JobId");
+ Name = table.AddStringColumn("Name", 200);
+ JobType = table.AddStringColumn("JobType", 200);
+ Frequency = table.AddStringColumn("Frequency", 1);
+ Interval = table.AddIntegerColumn("Interval");
+ StartDate = table.AddDateTimeColumn("StartDate", true);
+ EndDate = table.AddDateTimeColumn("EndDate", true);
+ IsEnabled = table.AddBooleanColumn("IsEnabled");
+ IsStarted = table.AddBooleanColumn("IsStarted");
+ IsExecuting = table.AddBooleanColumn("IsExecuting");
+ NextExecution = table.AddDateTimeColumn("NextExecution", true);
+ RetentionHistory = table.AddIntegerColumn("RetentionHistory");
+
+ AddAuditableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder JobId { get; set; }
+
+ public OperationBuilder Name { get; set; }
+
+ public OperationBuilder JobType { get; set; }
+
+ public OperationBuilder Frequency { get; set; }
+
+ public OperationBuilder Interval { get; set; }
+
+ public OperationBuilder StartDate { get; set; }
+
+ public OperationBuilder EndDate { get; set; }
+
+ public OperationBuilder IsEnabled { get; set; }
+
+ public OperationBuilder IsStarted { get; set; }
+
+ public OperationBuilder IsExecuting { get; set; }
+
+ public OperationBuilder NextExecution { get; set; }
+
+ public OperationBuilder RetentionHistory { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/JobLogEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/JobLogEntityBuilder.cs
new file mode 100644
index 00000000..e26c1f44
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/JobLogEntityBuilder.cs
@@ -0,0 +1,47 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class JobLogEntityBuilder : BaseEntityBuilder
+ {
+ private const string _entityTableName = "JobLog";
+ private readonly PrimaryKey _primaryKey = new("PK_JobLog", x => x.JobLogId);
+ private readonly ForeignKey _jobLogForeignKey = new("FK_JobLog_Job", x => x.JobId, "Job", "JobId", ReferentialAction.Cascade);
+
+ public JobLogEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_jobLogForeignKey);
+ }
+
+ protected override JobLogEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ JobLogId = table.AddAutoIncrementColumn("JobLogId");
+ JobId = table.AddIntegerColumn("JobId");
+ StartDate = table.AddDateTimeColumn("StartDate");
+ FinishDate = table.AddDateTimeColumn("FinishDate", true);
+ Succeeded = table.AddBooleanColumn("Succeeded", true);
+ Notes = table.AddMaxStringColumn("Notes", true);
+
+ return this;
+ }
+
+ public OperationBuilder JobLogId { get; private set; }
+
+ public OperationBuilder JobId { get; private set; }
+
+ public OperationBuilder StartDate { get; private set; }
+
+ public OperationBuilder FinishDate { get; private set; }
+
+ public OperationBuilder Succeeded { get; private set; }
+
+ public OperationBuilder Notes { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/LanguageEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/LanguageEntityBuilder.cs
new file mode 100644
index 00000000..b32e07ec
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/LanguageEntityBuilder.cs
@@ -0,0 +1,47 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class LanguageEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Language";
+ private readonly PrimaryKey _primaryKey = new("PK_Language", x => x.LanguageId);
+ private readonly ForeignKey _siteForeignKey = new("FK_Language_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
+
+ public LanguageEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_siteForeignKey);
+ }
+
+ protected override LanguageEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ LanguageId = table.AddAutoIncrementColumn("LanguageId");
+ SiteId = table.AddIntegerColumn("SiteId");
+ Name = table.AddStringColumn("Name", 100);
+ Code = table.AddStringColumn("Code", 10);
+ IsDefault = table.AddBooleanColumn("IsDefault");
+
+ AddAuditableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder LanguageId { get; set; }
+
+ public OperationBuilder SiteId { get; set; }
+
+ public OperationBuilder Name { get; set; }
+
+ public OperationBuilder Code { get; set; }
+
+ public OperationBuilder IsDefault { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/LogEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/LogEntityBuilder.cs
new file mode 100644
index 00000000..933e1256
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/LogEntityBuilder.cs
@@ -0,0 +1,78 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class LogEntityBuilder : BaseEntityBuilder
+ {
+ private const string _entityTableName = "Log";
+ private readonly PrimaryKey _primaryKey = new("PK_Log", x => x.LogId);
+ private readonly ForeignKey _siteForeignKey = new("FK_Log_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
+
+ public LogEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_siteForeignKey);
+ }
+
+ protected override LogEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ LogId = table.AddAutoIncrementColumn("LogId");
+ SiteId = table.AddIntegerColumn("SiteId", true);
+ LogDate = table.AddDateTimeColumn("LogDate");
+ PageId = table.AddIntegerColumn("PageId", true);
+ ModuleId = table.AddIntegerColumn("ModuleId", true);
+ UserId = table.AddIntegerColumn("UserId", true);
+ Url = table.AddStringColumn("Url", 2048);
+ Server = table.AddStringColumn("Server", 200);
+ Category = table.AddStringColumn("Category", 200);
+ Feature = table.AddStringColumn("Feature", 200);
+ Function = table.AddStringColumn("Function", 20);
+ Level = table.AddStringColumn("Level", 20);
+ Message = table.AddMaxStringColumn("Message");
+ MessageTemplate = table.AddMaxStringColumn("MessageTemplate");
+ Exception = table.AddMaxStringColumn("Exception", true);
+ Properties = table.AddMaxStringColumn("Properties", true);
+
+ return this;
+ }
+
+ public OperationBuilder LogId { get; set; }
+
+ public OperationBuilder SiteId { get; set; }
+
+ public OperationBuilder LogDate { get; set; }
+
+ public OperationBuilder PageId { get; set; }
+
+ public OperationBuilder ModuleId { get; set; }
+
+ public OperationBuilder UserId { get; set; }
+
+ public OperationBuilder Url { get; set; }
+
+ public OperationBuilder Server { get; set; }
+
+ public OperationBuilder Category { get; set; }
+
+ public OperationBuilder Feature { get; set; }
+
+ public OperationBuilder Function { get; set; }
+
+ public OperationBuilder Level { get; set; }
+
+ public OperationBuilder Message { get; set; }
+
+ public OperationBuilder MessageTemplate { get; set; }
+
+ public OperationBuilder Exception { get; set; }
+
+ public OperationBuilder Properties { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/ModuleDefinitionsEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/ModuleDefinitionsEntityBuilder.cs
new file mode 100644
index 00000000..5e7d5b50
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/ModuleDefinitionsEntityBuilder.cs
@@ -0,0 +1,48 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class ModuleDefinitionsEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "ModuleDefinition";
+ private readonly PrimaryKey _primaryKey = new("PK_ModuleDefinition", x => x.ModuleDefinitionId);
+
+ public ModuleDefinitionsEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ }
+
+ protected override ModuleDefinitionsEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ ModuleDefinitionId = table.AddAutoIncrementColumn("ModuleDefinitionId");
+ ModuleDefinitionName = table.AddStringColumn("ModuleDefinitionName", 200);
+ Name = table.AddStringColumn("Name", 200, true);
+ Description = table.AddStringColumn("Description", 2000, true);
+ Categories = table.AddStringColumn("Categories", 200, true);
+ Version = table.AddStringColumn("Version", 50, true);
+
+ AddAuditableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder ModuleDefinitionId { get; private set; }
+
+ public OperationBuilder ModuleDefinitionName { get; private set; }
+
+ public OperationBuilder Name { get; private set; }
+
+ public OperationBuilder Description { get; private set; }
+
+ public OperationBuilder Categories { get; private set; }
+
+ public OperationBuilder Version { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/ModuleEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/ModuleEntityBuilder.cs
new file mode 100644
index 00000000..96f8b270
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/ModuleEntityBuilder.cs
@@ -0,0 +1,44 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class ModuleEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Module";
+ private readonly PrimaryKey _primaryKey = new("PK_Module", x => x.ModuleId);
+ private readonly ForeignKey _siteForeignKey = new("FK_Module_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
+
+ public ModuleEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_siteForeignKey);
+ }
+
+ protected override ModuleEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ ModuleId = table.AddAutoIncrementColumn("ModuleId");
+ SiteId = table.AddIntegerColumn("SiteId");
+ ModuleDefinitionName = table.AddStringColumn("ModuleDefinitionName", 200);
+ AllPages = table.AddBooleanColumn("AllPages");
+
+ AddAuditableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder ModuleId { get; private set; }
+
+ public OperationBuilder SiteId { get; private set; }
+
+ public OperationBuilder ModuleDefinitionName { get; private set; }
+
+ public OperationBuilder AllPages { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/NotificationEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/NotificationEntityBuilder.cs
new file mode 100644
index 00000000..2ee3779b
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/NotificationEntityBuilder.cs
@@ -0,0 +1,65 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class NotificationEntityBuilder : DeletableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Notification";
+ private readonly PrimaryKey _primaryKey = new("PK_Notification", x => x.NotificationId);
+ private readonly ForeignKey _siteForeignKey = new("FK_Notification_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
+
+ public NotificationEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_siteForeignKey);
+ }
+
+ protected override NotificationEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ NotificationId = table.AddAutoIncrementColumn("NotificationId");
+ SiteId = table.AddIntegerColumn("SiteId");
+ FromUserId = table.AddIntegerColumn("FromUserId", true);
+ ToUserId = table.AddIntegerColumn("ToUserId", true);
+ ToEmail = table.AddStringColumn("ToEmail", 256);
+ ParentId = table.AddIntegerColumn("ParentId", true);
+ Subject = table.AddStringColumn("Subject", 256);
+ Body = table.AddMaxStringColumn("Body");
+ CreatedOn = table.AddDateTimeColumn("CreatedOn");
+ IsDelivered = table.AddBooleanColumn("IsDelivered");
+ DeliveredOn = table.AddDateTimeColumn("DeliveredOn", true);
+
+ AddDeletableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder NotificationId { get; set; }
+
+ public OperationBuilder SiteId { get; set; }
+
+ public OperationBuilder FromUserId { get; set; }
+
+ public OperationBuilder ToUserId { get; set; }
+
+ public OperationBuilder ToEmail { get; set; }
+
+ public OperationBuilder ParentId { get; set; }
+
+ public OperationBuilder Subject { get; set; }
+
+ public OperationBuilder Body { get; set; }
+
+ public OperationBuilder CreatedOn { get; set; }
+
+ public OperationBuilder IsDelivered { get; set; }
+
+ public OperationBuilder DeliveredOn { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/PageEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/PageEntityBuilder.cs
new file mode 100644
index 00000000..49c75ba0
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/PageEntityBuilder.cs
@@ -0,0 +1,80 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class PageEntityBuilder : DeletableAuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Page";
+ private readonly PrimaryKey _primaryKey = new("PK_Page", x => x.PageId);
+ private readonly ForeignKey _siteForeignKey = new("FK_Page_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
+
+ public PageEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_siteForeignKey);
+ }
+
+ protected override PageEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ PageId = table.AddAutoIncrementColumn("PageId");
+ SiteId = table.AddIntegerColumn("SiteId");
+ Path = table.AddStringColumn("Path", 50);
+ Name = table.AddStringColumn("Name", 50);
+ Title = table.AddStringColumn("Title", 200, true);
+ ThemeType = table.AddStringColumn("ThemeType", 200, true);
+ Icon = table.AddStringColumn("Icon", 50);
+ ParentId = table.AddIntegerColumn("ParentId", true);
+ Order = table.AddIntegerColumn("Order");
+ IsNavigation = table.AddBooleanColumn("IsNavigation");
+ Url = table.AddStringColumn("Url", 500, true);
+ LayoutType = table.AddStringColumn("LayoutType", 200);
+ EditMode = table.AddBooleanColumn("EditMode");
+ UserId = table.AddIntegerColumn("UserId", true);
+ IsPersonalizable = table.AddBooleanColumn("IsPersonalizable");
+ DefaultContainerType = table.AddStringColumn("DefaultContainerType", 200, true);
+
+ AddAuditableColumns(table);
+ AddDeletableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder PageId { get; private set; }
+
+ public OperationBuilder SiteId { get; private set; }
+
+ public OperationBuilder Path { get; private set; }
+ public OperationBuilder Name { get; private set; }
+
+ public OperationBuilder Title { get; private set; }
+
+ public OperationBuilder ThemeType { get; private set; }
+
+ public OperationBuilder Icon { get; private set; }
+
+ public OperationBuilder ParentId { get; private set; }
+
+ public OperationBuilder Order { get; private set; }
+
+ public OperationBuilder IsNavigation { get; private set; }
+
+ public OperationBuilder Url { get; private set; }
+
+ public OperationBuilder LayoutType { get; private set; }
+
+ public OperationBuilder EditMode { get; private set; }
+
+ public OperationBuilder UserId { get; private set; }
+
+ public OperationBuilder IsPersonalizable { get; private set; }
+
+ public OperationBuilder DefaultContainerType { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/PageModuleEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/PageModuleEntityBuilder.cs
new file mode 100644
index 00000000..ff9d0594
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/PageModuleEntityBuilder.cs
@@ -0,0 +1,56 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class PageModuleEntityBuilder : DeletableAuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "PageModule";
+ private readonly PrimaryKey _primaryKey = new("PK_PageModule", x => x.PageModuleId);
+ private readonly ForeignKey _moduleForeignKey = new("FK_PageModule_Module", x => x.ModuleId, "Module", "ModuleId", ReferentialAction.NoAction);
+ private readonly ForeignKey _pageForeignKey = new("FK_PageModule_Page", x => x.PageId, "Page", "PageId", ReferentialAction.Cascade);
+
+ public PageModuleEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_moduleForeignKey);
+ ForeignKeys.Add(_pageForeignKey);
+ }
+
+ protected override PageModuleEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ PageModuleId = table.AddAutoIncrementColumn("PageModuleId");
+ PageId = table.AddIntegerColumn("PageId");
+ ModuleId = table.AddIntegerColumn("ModuleId");
+ Title = table.AddStringColumn("Title", 200);
+ Pane = table.AddStringColumn("Pane", 50);
+ Order = table.AddIntegerColumn("Order");
+ ContainerType = table.AddStringColumn("ContainerType", 200);
+
+ AddAuditableColumns(table);
+ AddDeletableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder PageModuleId { get; private set; }
+
+ public OperationBuilder PageId { get; private set; }
+
+ public OperationBuilder ModuleId { get; private set; }
+
+ public OperationBuilder Title { get; private set; }
+
+ public OperationBuilder Pane { get; private set; }
+
+ public OperationBuilder Order { get; private set; }
+
+ public OperationBuilder ContainerType { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/PermissionEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/PermissionEntityBuilder.cs
new file mode 100644
index 00000000..af383609
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/PermissionEntityBuilder.cs
@@ -0,0 +1,60 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class PermissionEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Permission";
+ private readonly PrimaryKey _primaryKey = new("PK_Permission", x => x.PermissionId);
+ private readonly ForeignKey _siteForeignKey = new("FK_Permission_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
+ private readonly ForeignKey _userForeignKey = new("FK_Permission_User", x => x.UserId, "User", "UserId", ReferentialAction.NoAction);
+ private readonly ForeignKey _roleForeignKey = new("FK_Permission_Role", x => x.RoleId, "Role", "RoleId", ReferentialAction.NoAction);
+
+ public PermissionEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_siteForeignKey);
+ ForeignKeys.Add(_userForeignKey);
+ ForeignKeys.Add(_roleForeignKey);
+ }
+
+ protected override PermissionEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ PermissionId = table.AddAutoIncrementColumn("PermissionId");
+ SiteId = table.AddIntegerColumn("SiteId");
+ EntityName = table.AddStringColumn("EntityName", 50);
+ EntityId = table.AddIntegerColumn("EntityId");
+ PermissionName = table.AddStringColumn("PermissionName", 50);
+ RoleId = table.AddIntegerColumn("RoleId", true);
+ UserId = table.AddIntegerColumn("UserId", true);
+ IsAuthorized = table.AddBooleanColumn("IsAuthorized");
+
+ AddAuditableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder PermissionId { get; set; }
+
+ public OperationBuilder SiteId { get; set; }
+
+ public OperationBuilder EntityName { get; set; }
+
+ public OperationBuilder EntityId { get; set; }
+
+ public OperationBuilder PermissionName { get; set; }
+
+ public OperationBuilder RoleId { get; set; }
+
+ public OperationBuilder UserId { get; set; }
+
+ public OperationBuilder IsAuthorized { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/ProfileEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/ProfileEntityBuilder.cs
new file mode 100644
index 00000000..b5e27469
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/ProfileEntityBuilder.cs
@@ -0,0 +1,64 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class ProfileEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Profile";
+ private readonly PrimaryKey _primaryKey = new("PK_Profile", x => x.ProfileId);
+ private readonly ForeignKey _siteForeignKey = new("FK_Profile_Sites", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
+
+ public ProfileEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_siteForeignKey);
+ }
+
+ protected override ProfileEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ ProfileId = table.AddAutoIncrementColumn("ProfileId");
+ SiteId = table.AddIntegerColumn("SiteId", true);
+ Name = table.AddStringColumn("Name", 50);
+ Title = table.AddStringColumn("Title", 50);
+ Description = table.AddStringColumn("Description", 256, true);
+ Category = table.AddStringColumn("Category", 50);
+ ViewOrder = table.AddIntegerColumn("ViewOrder");
+ MaxLength = table.AddIntegerColumn("MaxLength");
+ DefaultValue = table.AddStringColumn("DefaultValue", 2000, true);
+ IsRequired = table.AddBooleanColumn("IsRequired");
+ IsPrivate = table.AddBooleanColumn("IsPrivate");
+
+ AddAuditableColumns(table);
+
+ return this; }
+
+ public OperationBuilder ProfileId { get; set; }
+
+ public OperationBuilder SiteId { get; set; }
+
+ public OperationBuilder Name { get; set; }
+
+ public OperationBuilder Title { get; set; }
+
+ public OperationBuilder Description { get; set; }
+
+ public OperationBuilder Category { get; set; }
+
+ public OperationBuilder ViewOrder { get; set; }
+
+ public OperationBuilder MaxLength { get; set; }
+
+ public OperationBuilder DefaultValue { get; set; }
+
+ public OperationBuilder IsRequired { get; set; }
+
+ public OperationBuilder IsPrivate { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/RoleEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/RoleEntityBuilder.cs
new file mode 100644
index 00000000..67deafa1
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/RoleEntityBuilder.cs
@@ -0,0 +1,50 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class RoleEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Role";
+ private readonly PrimaryKey _primaryKey = new("PK_Role", x => x.RoleId);
+ private readonly ForeignKey _siteForeignKey = new("FK_Role_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
+
+ public RoleEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ ForeignKeys.Add(_siteForeignKey);
+ }
+
+ protected override RoleEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ RoleId = table.AddAutoIncrementColumn("RoleId");
+ SiteId = table.AddIntegerColumn("SiteId", true);
+ Name = table.AddStringColumn("Name", 256);
+ Description = table.AddStringColumn("Description", 256);
+ IsAutoAssigned = table.AddBooleanColumn("IsAutoAssigned");
+ IsSystem = table.AddBooleanColumn("IsSystem");
+
+ AddAuditableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder RoleId { get; set; }
+
+ public OperationBuilder SiteId { get; set; }
+
+ public OperationBuilder Name { get; set; }
+
+ public OperationBuilder Description { get; set; }
+
+ public OperationBuilder IsAutoAssigned { get; set; }
+
+ public OperationBuilder IsSystem { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/SettingEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/SettingEntityBuilder.cs
new file mode 100644
index 00000000..7f4bb07d
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/SettingEntityBuilder.cs
@@ -0,0 +1,45 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class SettingEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Setting";
+ private readonly PrimaryKey _primaryKey = new("PK_Setting", x => x.SettingId);
+
+ public SettingEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ }
+
+ protected override SettingEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ SettingId = table.AddAutoIncrementColumn("SettingId");
+ EntityName = table.AddStringColumn("EntityName", 50);
+ EntityId = table.AddIntegerColumn("EntityId");
+ SettingName = table.AddStringColumn("SettingName", 50);
+ SettingValue = table.AddMaxStringColumn("SettingValue");
+
+ AddAuditableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder SettingId { get; set; }
+
+ public OperationBuilder EntityName { get; set; }
+
+ public OperationBuilder EntityId { get; set; }
+
+ public OperationBuilder SettingName { get; set; }
+
+ public OperationBuilder SettingValue { get; set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/SiteEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/SiteEntityBuilder.cs
new file mode 100644
index 00000000..172ff1df
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/SiteEntityBuilder.cs
@@ -0,0 +1,67 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class SiteEntityBuilder : DeletableAuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Site";
+ private readonly PrimaryKey _primaryKey = new("PK_Site", x => x.SiteId);
+
+ public SiteEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ }
+
+ protected override SiteEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ SiteId = table.AddAutoIncrementColumn("SiteId");
+ TenantId = table.AddIntegerColumn("TenantId");
+ Name = table.AddStringColumn("Name", 200);
+ LogoFileId = table.AddIntegerColumn("LogoFileId", true);
+ FaviconFileId = table.AddIntegerColumn("FaviconFileId", true);
+ DefaultThemeType = table.AddStringColumn("DefaultThemeType", 200);
+ DefaultLayoutType = table.AddStringColumn("DefaultLayoutType", 200);
+ DefaultContainerType = table.AddStringColumn("DefaultContainerType", 200);
+ PwaIsEnabled = table.AddBooleanColumn("PwaIsEnabled");
+ PwaAppIconFileId = table.AddIntegerColumn("PwaAppIconFileId", true);
+ PwaSplashIconFileId = table.AddIntegerColumn("PwaSplashIconFileId", true);
+ AllowRegistration = table.AddBooleanColumn("AllowRegistration");
+
+ AddAuditableColumns(table);
+ AddDeletableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder SiteId { get; private set; }
+
+ public OperationBuilder TenantId { get; private set; }
+
+ public OperationBuilder Name { get; private set; }
+
+ public OperationBuilder LogoFileId { get; private set; }
+
+ public OperationBuilder FaviconFileId { get; private set; }
+
+ public OperationBuilder DefaultThemeType { get; private set; }
+
+ public OperationBuilder DefaultLayoutType { get; private set; }
+
+ public OperationBuilder DefaultContainerType { get; private set; }
+
+ public OperationBuilder PwaIsEnabled { get; private set; }
+
+ public OperationBuilder PwaAppIconFileId { get; private set; }
+
+ public OperationBuilder PwaSplashIconFileId { get; private set; }
+
+ public OperationBuilder AllowRegistration { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/TenantEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/TenantEntityBuilder.cs
new file mode 100644
index 00000000..1cf04a30
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/TenantEntityBuilder.cs
@@ -0,0 +1,42 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class TenantEntityBuilder : AuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "Tenant";
+ private readonly PrimaryKey _primaryKey = new("PK_Tenant", x => x.TenantId);
+
+ public TenantEntityBuilder(MigrationBuilder migrationBuilder): base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ }
+
+ protected override TenantEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ TenantId = table.AddAutoIncrementColumn("TenantId");
+ Name = table.AddStringColumn("Name", 100);
+ DBConnectionString = table.AddStringColumn("DBConnectionString", 1024);
+ Version = table.AddStringColumn("Version", 50, true);
+
+ AddAuditableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder TenantId { get; private set; }
+
+ public OperationBuilder Name { get;private set; }
+
+ public OperationBuilder DBConnectionString { get; private set;}
+
+ public OperationBuilder Version { get; private set; }
+ }
+}
diff --git a/Oqtane.Server/Migrations/EntityBuilders/UserEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/UserEntityBuilder.cs
new file mode 100644
index 00000000..cfcf6acb
--- /dev/null
+++ b/Oqtane.Server/Migrations/EntityBuilders/UserEntityBuilder.cs
@@ -0,0 +1,52 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations;
+using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
+using Oqtane.Migrations.Extensions;
+
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+namespace Oqtane.Migrations.EntityBuilders
+{
+ public class UserEntityBuilder : DeletableAuditableBaseEntityBuilder
+ {
+ private const string _entityTableName = "User";
+ private readonly PrimaryKey _primaryKey = new("PK_User", x => x.UserId);
+
+ public UserEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder)
+ {
+ EntityTableName = _entityTableName;
+ PrimaryKey = _primaryKey;
+ }
+
+ protected override UserEntityBuilder BuildTable(ColumnsBuilder table)
+ {
+ UserId = table.AddAutoIncrementColumn("UserId");
+ Username = table.AddStringColumn("Username", 256);
+ DisplayName = table.AddStringColumn("DisplayName", 50);
+ Email = table.AddStringColumn("Email", 256);
+ PhotoFileId = table.AddIntegerColumn("PhotoFileId", true);
+ LastLoginOn = table.AddDateTimeColumn("LastLoginOn", true);
+ LastIPAddress = table.AddStringColumn("LastIpAddress", 50);
+
+ AddAuditableColumns(table);
+ AddDeletableColumns(table);
+
+ return this;
+ }
+
+ public OperationBuilder