From 8c45b7e42ffba1642c26264e8c01b9af160514a4 Mon Sep 17 00:00:00 2001 From: Charles Nurse Date: Thu, 8 Apr 2021 12:20:21 -0700 Subject: [PATCH] Added support for migrating existing Oqtane installations from DbUp to Migrations. Also added a Migration for version 2.0.2, and set current version to 2.1.0 --- .../Infrastructure/DatabaseManager.cs | 115 +++++++++++------- .../Migrations/02000201_AddSiteGuidToSite.cs | 34 ++++++ .../02010000_AddAppVersionsTableInTenant.cs | 75 ++++++++++++ .../AppVersionsEntityBuilder.cs | 35 ++++++ .../EntityBuilders/BaseEntityBuilder.cs | 20 +-- Oqtane.Server/Oqtane.Server.csproj | 2 + .../Repository/Interfaces/ISqlRepository.cs | 5 + Oqtane.Server/Repository/SqlRepository.cs | 84 +++++++++---- Oqtane.Server/Scripts/MigrateMaster.sql | 17 +++ Oqtane.Server/Scripts/MigrateTenant.sql | 20 +++ Oqtane.Shared/Shared/Constants.cs | 4 +- 11 files changed, 331 insertions(+), 80 deletions(-) create mode 100644 Oqtane.Server/Migrations/02000201_AddSiteGuidToSite.cs create mode 100644 Oqtane.Server/Migrations/02010000_AddAppVersionsTableInTenant.cs create mode 100644 Oqtane.Server/Migrations/EntityBuilders/AppVersionsEntityBuilder.cs create mode 100644 Oqtane.Server/Scripts/MigrateMaster.sql create mode 100644 Oqtane.Server/Scripts/MigrateTenant.sql diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs index bad8c272..18dc820f 100644 --- a/Oqtane.Server/Infrastructure/DatabaseManager.cs +++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Memory; @@ -75,7 +76,13 @@ namespace Oqtane.Infrastructure if (install == null) { // startup or silent installation - install = new InstallConfig { ConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey), TenantName = TenantNames.Master, IsNewTenant = false }; + install = new InstallConfig + { + ConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey), + TenantName = TenantNames.Master, + DatabaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey], + IsNewTenant = false + }; if (!IsInstalled()) { @@ -207,6 +214,7 @@ namespace Oqtane.Infrastructure using (var scope = _serviceScopeFactory.CreateScope()) { var databases = scope.ServiceProvider.GetServices(); + var sql = scope.ServiceProvider.GetRequiredService(); try { @@ -214,6 +222,10 @@ namespace Oqtane.Infrastructure using (var masterDbContext = new MasterDBContext(new DbContextOptions(), dbConfig)) { + if (IsInstalled() && (install.DatabaseType == "SqlServer" || install.DatabaseType == "LocalDB")) + { + UpgradeSqlServer(sql, install.ConnectionString, true); + } // Push latest model into database masterDbContext.Database.Migrate(); result.Success = true; @@ -303,14 +315,6 @@ namespace Oqtane.Infrastructure return result; } - private InstallationContext GetInstallationContext(IEnumerable databases) - { - var databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey]; - var connectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey)); - - return new InstallationContext(databases.Single(d => d.Name == databaseType), connectionString); - } - private Installation MigrateTenants(InstallConfig install) { var result = new Installation { Success = false, Message = string.Empty }; @@ -321,6 +325,7 @@ namespace Oqtane.Infrastructure { var upgrades = scope.ServiceProvider.GetRequiredService(); var databases = scope.ServiceProvider.GetServices(); + var sql = scope.ServiceProvider.GetRequiredService(); using (var db = GetInstallationContext(databases)) { @@ -328,9 +333,14 @@ namespace Oqtane.Infrastructure { try { - var dbConfig = new DbConfig(null, null, databases) {ConnectionString = install.ConnectionString, DatabaseType = install.DatabaseType}; + var dbConfig = new DbConfig(null, null, databases) {ConnectionString = tenant.DBConnectionString, DatabaseType = tenant.DBType}; using (var tenantDbContext = new TenantDBContext(dbConfig, null)) { + if (install.DatabaseType == "SqlServer" || install.DatabaseType == "LocalDB") + { + UpgradeSqlServer(sql, tenant.DBConnectionString, false); + } + // Push latest model into database tenantDbContext.Database.Migrate(); result.Success = true; @@ -551,36 +561,6 @@ namespace Oqtane.Infrastructure return result; } - private string NormalizeConnectionString(string connectionString) - { - var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString(); - connectionString = connectionString.Replace("|DataDirectory|", dataDirectory); - return connectionString; - } - - private string DenormalizeConnectionString(string connectionString) - { - var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString(); - connectionString = connectionString.Replace(dataDirectory ?? String.Empty, "|DataDirectory|"); - return connectionString; - } - - public void UpdateConnectionString(string connectionString) - { - connectionString = DenormalizeConnectionString(connectionString); - if (_config.GetConnectionString(SettingKeys.ConnectionStringKey) != connectionString) - { - AddOrUpdateAppSetting($"{SettingKeys.ConnectionStringsSection}:{SettingKeys.ConnectionStringKey}", connectionString); - _config.Reload(); - } - } - - public void UpdateDatabaseType(string databaseType) - { - AddOrUpdateAppSetting($"{SettingKeys.DatabaseSection}:{SettingKeys.DatabaseTypeKey}", databaseType); - _config.Reload(); - } - public void AddOrUpdateAppSetting(string sectionPathKey, T value) { try @@ -600,6 +580,36 @@ namespace Oqtane.Infrastructure } } + private string DenormalizeConnectionString(string connectionString) + { + var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString(); + connectionString = connectionString.Replace(dataDirectory ?? String.Empty, "|DataDirectory|"); + return connectionString; + } + + private InstallationContext GetInstallationContext(IEnumerable databases) + { + var databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey]; + var connectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey)); + + return new InstallationContext(databases.Single(d => d.Name == databaseType), connectionString); + } + + private string GetInstallationConfig(string key, string defaultValue) + { + var value = _config.GetSection(SettingKeys.InstallationSection).GetValue(key, defaultValue); + // double fallback to default value - allow hold sample keys in config + if (string.IsNullOrEmpty(value)) value = defaultValue; + return value; + } + + private string NormalizeConnectionString(string connectionString) + { + var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString(); + connectionString = connectionString.Replace("|DataDirectory|", dataDirectory); + return connectionString; + } + private void SetValueRecursively(string sectionPathKey, dynamic jsonObj, T value) { // split the string at the first ':' character @@ -619,12 +629,27 @@ namespace Oqtane.Infrastructure } } - private string GetInstallationConfig(string key, string defaultValue) + public void UpdateConnectionString(string connectionString) { - var value = _config.GetSection(SettingKeys.InstallationSection).GetValue(key, defaultValue); - // double fallback to default value - allow hold sample keys in config - if (string.IsNullOrEmpty(value)) value = defaultValue; - return value; + connectionString = DenormalizeConnectionString(connectionString); + if (_config.GetConnectionString(SettingKeys.ConnectionStringKey) != connectionString) + { + AddOrUpdateAppSetting($"{SettingKeys.ConnectionStringsSection}:{SettingKeys.ConnectionStringKey}", connectionString); + _config.Reload(); + } + } + + public void UpdateDatabaseType(string databaseType) + { + AddOrUpdateAppSetting($"{SettingKeys.DatabaseSection}:{SettingKeys.DatabaseTypeKey}", databaseType); + _config.Reload(); + } + + public void UpgradeSqlServer(ISqlRepository sql, string connectionString, bool isMaster) + { + var script = (isMaster) ? "MigrateMaster.sql" : "MigrateTenant.sql"; + + sql.ExecuteScript(connectionString, Assembly.GetExecutingAssembly(), script); } } } diff --git a/Oqtane.Server/Migrations/02000201_AddSiteGuidToSite.cs b/Oqtane.Server/Migrations/02000201_AddSiteGuidToSite.cs new file mode 100644 index 00000000..45484d92 --- /dev/null +++ b/Oqtane.Server/Migrations/02000201_AddSiteGuidToSite.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Oqtane.Interfaces; +using Oqtane.Migrations.EntityBuilders; +using Oqtane.Repository; + +namespace Oqtane.Migrations +{ + [DbContext(typeof(TenantDBContext))] + [Migration("Tenant.02.00.02.01")] + + public class AddSiteGuidToSite : MultiDatabaseMigration + { + public AddSiteGuidToSite(IEnumerable databases) : base(databases) + { + } + + protected override void Up(MigrationBuilder migrationBuilder) + { + //Add Column to Site table + var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase); + siteEntityBuilder.AddStringColumn("SiteGuid", 36, true, false); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + //Drop Column from Site table + var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase); + siteEntityBuilder.DropColumn("SiteGuid"); + } + + } +} diff --git a/Oqtane.Server/Migrations/02010000_AddAppVersionsTableInTenant.cs b/Oqtane.Server/Migrations/02010000_AddAppVersionsTableInTenant.cs new file mode 100644 index 00000000..f2a65ab7 --- /dev/null +++ b/Oqtane.Server/Migrations/02010000_AddAppVersionsTableInTenant.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Oqtane.Interfaces; +using Oqtane.Migrations.EntityBuilders; +using Oqtane.Repository; + +namespace Oqtane.Migrations +{ + [DbContext(typeof(TenantDBContext))] + [Migration("Tenant.02.01.00.00")] + + public class AddAppVersionsTable : MultiDatabaseMigration + { + public AddAppVersionsTable(IEnumerable databases) : base(databases) + { + } + + protected override void Up(MigrationBuilder migrationBuilder) + { + //Create AppVersions table + var appVersionsEntityBuilder = new AppVersionsEntityBuilder(migrationBuilder, ActiveDatabase); + appVersionsEntityBuilder.Create(); + + //Finish SqlServer Migration from DbUp + if (ActiveDatabase.Name == "SqlServer" || ActiveDatabase.Name == "LocalDB") + { + //Version 1.0.0 + InsertVersion(migrationBuilder, "01.00.00", "Oqtane.Scripts.Master.00.09.00.00.sql"); + + //Version 1.0.1 + InsertVersion(migrationBuilder, "01.00.01", "Oqtane.Scripts.Master.01.00.01.00.sql"); + + //Version 1.0.2 + InsertVersion(migrationBuilder, "01.00.02", "Oqtane.Scripts.Tenant.01.00.02.01.sql"); + + //Version 2.0.0 + InsertVersion(migrationBuilder, "02.00.00", "Oqtane.Scripts.Tenant.02.00.00.01.sql"); + + //Version 2.0.1 + InsertVersion(migrationBuilder, "02.00.01", "Oqtane.Scripts.Tenant.02.00.01.03.sql"); + + //Version 2.0.2 + InsertVersion(migrationBuilder, "02.00.02", "Oqtane.Scripts.Tenant.02.00.02.01.sql"); + + //Drop SchemaVersions + migrationBuilder.Sql(@" + IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.SchemaVersions') AND OBJECTPROPERTY(id, N'IsTable') = 1) + BEGIN + DROP TABLE SchemaVersions + END"); + } + + //Version 2.1.0 + migrationBuilder.Sql($@" + INSERT INTO AppVersions(Version, AppliedDate) + VALUES('02.01.00', '{DateTime.UtcNow:u}') + "); + } + + private void InsertVersion(MigrationBuilder migrationBuilder, string version, string scriptName) + { + migrationBuilder.Sql($@" + IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.SchemaVersions') AND OBJECTPROPERTY(id, N'IsTable') = 1) + BEGIN + INSERT INTO AppVersions(Version, AppliedDate) + SELECT Version = '{version}', Applied As AppliedDate + FROM SchemaVersions + WHERE ScriptName = '{scriptName}' + END + "); + } + } +} diff --git a/Oqtane.Server/Migrations/EntityBuilders/AppVersionsEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/AppVersionsEntityBuilder.cs new file mode 100644 index 00000000..7c5581ff --- /dev/null +++ b/Oqtane.Server/Migrations/EntityBuilders/AppVersionsEntityBuilder.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations.Operations; +using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; +using Oqtane.Interfaces; + +namespace Oqtane.Migrations.EntityBuilders +{ + public class AppVersionsEntityBuilder : BaseEntityBuilder + { + private const string _entityTableName = "AppVersions"; + private readonly PrimaryKey _primaryKey = new("PK_AppVersions", x => x.Id); + + public AppVersionsEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database) + { + EntityTableName = _entityTableName; + PrimaryKey = _primaryKey; + } + + protected override AppVersionsEntityBuilder BuildTable(ColumnsBuilder table) + { + Id = AddAutoIncrementColumn(table,"Id"); + Version = AddStringColumn(table,"Version", 10); + AppliedDate = AddDateTimeColumn(table,"AppliedDate"); + + return this; + } + + public OperationBuilder Id { get; set; } + + public OperationBuilder Version { get; set; } + + public OperationBuilder AppliedDate { get; set; } + + } +} diff --git a/Oqtane.Server/Migrations/EntityBuilders/BaseEntityBuilder.cs b/Oqtane.Server/Migrations/EntityBuilders/BaseEntityBuilder.cs index 42264996..77022a9f 100644 --- a/Oqtane.Server/Migrations/EntityBuilders/BaseEntityBuilder.cs +++ b/Oqtane.Server/Migrations/EntityBuilders/BaseEntityBuilder.cs @@ -83,29 +83,29 @@ namespace Oqtane.Migrations.EntityBuilders return table.Column(name: RewriteName(name), nullable: nullable); } - public void AddMaxStringColumn(string name, int length, bool nullable = false) + public void AddMaxStringColumn(string name, int length, bool nullable = false, bool unicode = true) { - _migrationBuilder.AddColumn(RewriteName(name), RewriteName(EntityTableName), nullable: nullable, unicode: true); + _migrationBuilder.AddColumn(RewriteName(name), RewriteName(EntityTableName), nullable: nullable, unicode: unicode); } - protected OperationBuilder AddMaxStringColumn(ColumnsBuilder table, string name, bool nullable = false) + protected OperationBuilder AddMaxStringColumn(ColumnsBuilder table, string name, bool nullable = false, bool unicode = true) { - return table.Column(name: RewriteName(name), nullable: nullable, unicode: true); + return table.Column(name: RewriteName(name), nullable: nullable, unicode: unicode); } - public void AddStringColumn(string name, int length, bool nullable = false) + public void AddStringColumn(string name, int length, bool nullable = false, bool unicode = true) { - _migrationBuilder.AddColumn(RewriteName(name), RewriteName(EntityTableName), maxLength: length, nullable: nullable, unicode: true); + _migrationBuilder.AddColumn(RewriteName(name), RewriteName(EntityTableName), maxLength: length, nullable: nullable, unicode: unicode); } - protected OperationBuilder AddStringColumn(ColumnsBuilder table, string name, int length, bool nullable = false) + protected OperationBuilder AddStringColumn(ColumnsBuilder table, string name, int length, bool nullable = false, bool unicode = true) { - return table.Column(name: RewriteName(name), maxLength: length, nullable: nullable, unicode: true); + return table.Column(name: RewriteName(name), maxLength: length, nullable: nullable, unicode: unicode); } - public void AlterStringColumn(string name, int length, bool nullable = false) + public void AlterStringColumn(string name, int length, bool nullable = false, bool unicode = true) { - _migrationBuilder.AlterColumn(RewriteName(name), RewriteName(EntityTableName), maxLength: length, nullable: nullable); + _migrationBuilder.AlterColumn(RewriteName(name), RewriteName(EntityTableName), maxLength: length, nullable: nullable, unicode: unicode); } public void DropColumn(string name) diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index 8898841a..af44052f 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -39,6 +39,8 @@ + + diff --git a/Oqtane.Server/Repository/Interfaces/ISqlRepository.cs b/Oqtane.Server/Repository/Interfaces/ISqlRepository.cs index 76a6f701..4d53fce6 100644 --- a/Oqtane.Server/Repository/Interfaces/ISqlRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/ISqlRepository.cs @@ -7,8 +7,13 @@ namespace Oqtane.Repository public interface ISqlRepository { void ExecuteScript(Tenant tenant, string script); + + bool ExecuteScript(string connectionString, Assembly assembly, string filename); + bool ExecuteScript(Tenant tenant, Assembly assembly, string filename); + int ExecuteNonQuery(Tenant tenant, string query); + SqlDataReader ExecuteReader(Tenant tenant, string query); } } diff --git a/Oqtane.Server/Repository/SqlRepository.cs b/Oqtane.Server/Repository/SqlRepository.cs index 037a9e42..6a35876a 100644 --- a/Oqtane.Server/Repository/SqlRepository.cs +++ b/Oqtane.Server/Repository/SqlRepository.cs @@ -5,6 +5,9 @@ using System.Linq; using System.Reflection; using Microsoft.Data.SqlClient; using Oqtane.Models; +// ReSharper disable ConvertToUsingDeclaration +// ReSharper disable InvertIf +// ReSharper disable BuiltInTypeReferenceStyleForMemberAccess namespace Oqtane.Repository { @@ -13,35 +16,41 @@ namespace Oqtane.Repository public void ExecuteScript(Tenant tenant, string script) { - // execute script in curent tenant - foreach (string query in script.Split("GO", StringSplitOptions.RemoveEmptyEntries)) + // execute script in current tenant + foreach (var query in script.Split("GO", StringSplitOptions.RemoveEmptyEntries)) { ExecuteNonQuery(tenant, query); } } - public bool ExecuteScript(Tenant tenant, Assembly assembly, string filename) + public bool ExecuteScript(string connectionString, Assembly assembly, string fileName) { - // script must be included as an Embedded Resource within an assembly - bool success = true; - string script = ""; + var success = true; + var script = GetScriptFromAssembly(assembly, fileName); - if (assembly != null) + if (!string.IsNullOrEmpty(script)) { - string name = assembly.GetManifestResourceNames().FirstOrDefault(item => item.EndsWith("." + filename)); - if (name != null) + try { - Stream resourceStream = assembly.GetManifestResourceStream(name); - if (resourceStream != null) + foreach (var query in script.Split("GO", StringSplitOptions.RemoveEmptyEntries)) { - using (var reader = new StreamReader(resourceStream)) - { - script = reader.ReadToEnd(); - } + ExecuteNonQuery(connectionString, query); } } + catch + { + success = false; + } } + return success; + } + + public bool ExecuteScript(Tenant tenant, Assembly assembly, string fileName) + { + var success = true; + var script = GetScriptFromAssembly(assembly, fileName); + if (!string.IsNullOrEmpty(script)) { try @@ -59,12 +68,26 @@ namespace Oqtane.Repository public int ExecuteNonQuery(Tenant tenant, string query) { - var conn = new SqlConnection(FormatConnectionString(tenant.DBConnectionString)); + return ExecuteNonQuery(tenant.DBConnectionString, query); + } + + public SqlDataReader ExecuteReader(Tenant tenant, string query) + { + SqlConnection conn = new SqlConnection(FormatConnectionString(tenant.DBConnectionString)); + SqlCommand cmd = conn.CreateCommand(); + PrepareCommand(conn, cmd, query); + var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); + return dr; + } + + private int ExecuteNonQuery(string connectionString, string query) + { + var conn = new SqlConnection(FormatConnectionString(connectionString)); var cmd = conn.CreateCommand(); using (conn) { PrepareCommand(conn, cmd, query); - int val = -1; + var val = -1; try { val = cmd.ExecuteNonQuery(); @@ -77,13 +100,28 @@ namespace Oqtane.Repository } } - public SqlDataReader ExecuteReader(Tenant tenant, string query) + private string GetScriptFromAssembly(Assembly assembly, string fileName) { - SqlConnection conn = new SqlConnection(FormatConnectionString(tenant.DBConnectionString)); - SqlCommand cmd = conn.CreateCommand(); - PrepareCommand(conn, cmd, query); - var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); - return dr; + // script must be included as an Embedded Resource within an assembly + var script = ""; + + if (assembly != null) + { + var name = assembly.GetManifestResourceNames().FirstOrDefault(item => item.EndsWith("." + fileName)); + if (name != null) + { + var resourceStream = assembly.GetManifestResourceStream(name); + if (resourceStream != null) + { + using (var reader = new StreamReader(resourceStream)) + { + script = reader.ReadToEnd(); + } + } + } + } + + return script; } private void PrepareCommand(SqlConnection conn, SqlCommand cmd, string query) diff --git a/Oqtane.Server/Scripts/MigrateMaster.sql b/Oqtane.Server/Scripts/MigrateMaster.sql new file mode 100644 index 00000000..3da59696 --- /dev/null +++ b/Oqtane.Server/Scripts/MigrateMaster.sql @@ -0,0 +1,17 @@ +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.SchemaVersions') AND OBJECTPROPERTY(id, N'IsTable') = 1) + BEGIN + IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.__EFMigrationsHistory') AND OBJECTPROPERTY(id, N'IsTable') = 1) + BEGIN + CREATE TABLE __EFMigrationsHistory + ( + MigrationId nvarchar(150) NOT NULL CONSTRAINT PK___EFMigrationsHistory PRIMARY KEY, + ProductVersion nvarchar(32) NOT NULL + ) + END + INSERT INTO __EFMigrationsHistory(MigrationId, ProductVersion) + VALUES ('Master.01.00.00.00', '5.0.0') + INSERT INTO __EFMigrationsHistory(MigrationId, ProductVersion) + SELECT REPLACE(REPLACE(ScriptName, 'Oqtane.Scripts.', ''), '.sql', '') As MigrationId, ProductVersion = '5.0.0' + FROM SchemaVersions + WHERE ScriptName LIKE 'Oqtane.Scripts.Master.01%' + END \ No newline at end of file diff --git a/Oqtane.Server/Scripts/MigrateTenant.sql b/Oqtane.Server/Scripts/MigrateTenant.sql new file mode 100644 index 00000000..ca4ae38e --- /dev/null +++ b/Oqtane.Server/Scripts/MigrateTenant.sql @@ -0,0 +1,20 @@ +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.SchemaVersions') AND OBJECTPROPERTY(id, N'IsTable') = 1) + BEGIN + IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.__EFMigrationsHistory') AND OBJECTPROPERTY(id, N'IsTable') = 1) + BEGIN + CREATE TABLE __EFMigrationsHistory + ( + MigrationId nvarchar(150) NOT NULL CONSTRAINT PK___EFMigrationsHistory PRIMARY KEY, + ProductVersion nvarchar(32) NOT NULL + ) + END + INSERT INTO __EFMigrationsHistory(MigrationId, ProductVersion) + VALUES ('Tenant.01.00.00.00', '5.0.0') + INSERT INTO __EFMigrationsHistory(MigrationId, ProductVersion) + SELECT REPLACE(REPLACE(ScriptName, 'Oqtane.Scripts.', ''), '.sql', '') As MigrationId, ProductVersion = '5.0.0' + FROM SchemaVersions + WHERE ScriptName LIKE 'Oqtane.Scripts.Tenant.01%' + OR ScriptName LIKE 'Oqtane.Scripts.Tenant.02%' + INSERT INTO __EFMigrationsHistory(MigrationId, ProductVersion) + VALUES ('HtmlText.01.00.00.00', '5.0.0') + END \ No newline at end of file diff --git a/Oqtane.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs index 1b05a7e7..e7636ed0 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -5,8 +5,8 @@ namespace Oqtane.Shared { public class Constants { public const string PackageId = "Oqtane.Framework"; - public const string Version = "2.0.1"; - public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1"; + public const string Version = "2.1.0"; + public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0"; public const string PageComponent = "Oqtane.UI.ThemeBuilder, Oqtane.Client"; public const string ContainerComponent = "Oqtane.UI.ContainerBuilder, Oqtane.Client";