Added suuport to inject an IOqtaneDatabase in EntityBuilders to allow each Database to control certain Migration behaviors. Also updated Installer to dynamically build Database Configuration section

This commit is contained in:
Charles Nurse
2021-03-27 11:16:16 -07:00
parent 3a032f401a
commit 2fb63e8117
74 changed files with 1028 additions and 407 deletions

View File

@ -87,7 +87,7 @@ namespace Oqtane.Client
} }
// dynamically register database providers // dynamically register database providers
var databaseTypes = assembly.GetInterfaces<IDatabase>(); var databaseTypes = assembly.GetInterfaces<IOqtaneDatabase>();
foreach (var databaseType in databaseTypes) foreach (var databaseType in databaseTypes)
{ {
if (databaseType.AssemblyQualifiedName != null) if (databaseType.AssemblyQualifiedName != null)

View File

@ -1,4 +1,5 @@
@using Oqtane.Interfaces @using Oqtane.Interfaces
@using System.Reflection
@namespace Oqtane.UI @namespace Oqtane.UI
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IInstallationService InstallationService @inject IInstallationService InstallationService
@ -6,7 +7,7 @@
@inject IUserService UserService @inject IUserService UserService
@inject IJSRuntime JSRuntime @inject IJSRuntime JSRuntime
@inject IStringLocalizer<Installer> Localizer @inject IStringLocalizer<Installer> Localizer
@inject IEnumerable<IDatabase> Databases @inject IEnumerable<IOqtaneDatabase> Databases
<div class="container"> <div class="container">
<div class="row"> <div class="row">
@ -36,57 +37,50 @@
</select> </select>
</td> </td>
</tr> </tr>
<tr style="@(_databaseType == "Sqlite" ? "" : "display: none")"> @{
<td> _selectedDatabase = Databases.Single(d => d.Name == _databaseType);
<label class="control-label" style="font-weight: bold">@Localizer["File Name:"] </label> foreach (var field in _selectedDatabase.ConnectionStringFields)
</td> {
<td> if (field.Name != "IntegratedSecurity")
<input type="text" class="form-control" @bind="@_fileName" /> {
</td> var isVisible = "";
</tr> var fieldType = (field.Name == "Pwd") ? "password" : "text";
<tr style="@(_databaseType == "Sqlite" ? "display: none" : "")"> if ((field.Name == "Uid" || field.Name == "Pwd") && _selectedDatabase.Name != "MySQL" )
<td> {
<label class="control-label" style="font-weight: bold">@Localizer["Server:"] </label> var intSecurityField = _selectedDatabase.ConnectionStringFields.Single(f => f.Name == "IntegratedSecurity");
</td> if (intSecurityField != null)
<td> {
<input type="text" class="form-control" @bind="@_serverName" /> isVisible = (Convert.ToBoolean(intSecurityField.Value)) ? "display: none;" : "";
</td> }
</tr> }
<tr style="@(_databaseType == "Sqlite" ? "display: none" : "")">
<td> field.Value = field.Value.Replace("{{Date}}", DateTime.UtcNow.ToString("yyyyMMddHHmm"));
<label class="control-label" style="font-weight: bold">@Localizer["Database:"] </label>
</td> <tr style="@isVisible">
<td> <td>
<input type="text" class="form-control" @bind="@_databaseName" /> <label class="control-label" style="font-weight: bold">@Localizer[$"{field.FriendlyName}:"]</label>
</td> </td>
</tr> <td>
<tr style="@(_databaseType == "Sqlite" ? "display: none" : "")"> <input type="@fieldType" class="form-control" @bind="@field.Value" />
<td> </td>
<label class="control-label" style="font-weight: bold">@Localizer["Integrated Security:"] </label> </tr>
</td> }
<td> else
<select class="custom-select" @onchange="SetIntegratedSecurity"> {
<option value="true" selected>@Localizer["True"]</option> <tr>
<option value="false">@Localizer["False"]</option> <td>
</select> <label class="control-label" style="font-weight: bold">@Localizer[$"{field.FriendlyName}:"]</label>
</td> </td>
</tr> <td>
<tr style="@_integratedSecurityDisplay"> <select class="custom-select" @bind="@field.Value">
<td> <option value="true" selected>@Localizer["True"]</option>
<label class="control-label" style="font-weight: bold">@Localizer["Username:"] </label> <option value="false">@Localizer["False"]</option>
</td> </select>
<td> </td>
<input type="text" class="form-control" @bind="@_username" /> </tr>
</td> }
</tr> }
<tr style="@_integratedSecurityDisplay"> }
<td>
<label class="control-label" style="font-weight: bold">@Localizer["Password:"] </label>
</td>
<td>
<input type="password" class="form-control" @bind="@_password" />
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
@ -141,18 +135,13 @@
</div> </div>
@code { @code {
private IOqtaneDatabase _selectedDatabase;
private string _databaseType = "LocalDB"; private string _databaseType = "LocalDB";
private string _serverName = "(LocalDb)\\MSSQLLocalDB";
private string _fileName = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm") + ".db";
private string _databaseName = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm");
private string _username = string.Empty;
private string _password = string.Empty;
private string _hostUsername = UserNames.Host; private string _hostUsername = UserNames.Host;
private string _hostPassword = string.Empty; private string _hostPassword = string.Empty;
private string _confirmPassword = string.Empty; private string _confirmPassword = string.Empty;
private string _hostEmail = string.Empty; private string _hostEmail = string.Empty;
private string _message = string.Empty; private string _message = string.Empty;
private string _integratedSecurityDisplay = "display: none;";
private string _loadingDisplay = "display: none;"; private string _loadingDisplay = "display: none;";
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
@ -164,52 +153,21 @@
} }
} }
private void SetIntegratedSecurity(ChangeEventArgs e)
{
_integratedSecurityDisplay = Convert.ToBoolean((string)e.Value)
? "display: none;"
: string.Empty;
}
private async Task Install() private async Task Install()
{ {
if (((_serverName != "" && _databaseName != "") || _fileName !="") && _hostUsername != "" && _hostPassword.Length >= 6 && _hostPassword == _confirmPassword && _hostEmail != "") var connectionString = _selectedDatabase.BuildConnectionString();
if (connectionString != "" && _hostUsername != "" && _hostPassword.Length >= 6 && _hostPassword == _confirmPassword && _hostEmail != "")
{ {
_loadingDisplay = ""; _loadingDisplay = "";
StateHasChanged(); StateHasChanged();
var connectionstring = "";
var fullyQualifiedType = "";
switch (_databaseType)
{
case "LocalDB":
connectionstring = "Data Source=" + _serverName + ";AttachDbFilename=|DataDirectory|\\" + _databaseName + ".mdf;Initial Catalog=" + _databaseName + ";Integrated Security=SSPI;";
fullyQualifiedType = "Oqtane.Repository.Databases.LocalDbDatabase, Oqtane.Server";
break;
case "SQLServer":
connectionstring = "Data Source=" + _serverName + ";Initial Catalog=" + _databaseName + ";";
if (_integratedSecurityDisplay == "display: none;")
{
connectionstring += "Integrated Security=SSPI;";
}
else
{
connectionstring += "User ID=" + _username + ";Password=" + _password;
}
fullyQualifiedType = "Oqtane.Repository.Databases.SqlServerDatabase, Oqtane.Server";
break;
case "Sqlite":
connectionstring = "Data Source=" + _fileName;
fullyQualifiedType = "Oqtane.Repository.Databases.SqliteDatabase, Oqtane.Server";
break;
}
Uri uri = new Uri(NavigationManager.Uri); Uri uri = new Uri(NavigationManager.Uri);
var config = new InstallConfig var config = new InstallConfig
{ {
DatabaseType = fullyQualifiedType, DatabaseType = _databaseType,
ConnectionString = connectionstring, ConnectionString = connectionString,
Aliases = uri.Authority, Aliases = uri.Authority,
HostEmail = _hostEmail, HostEmail = _hostEmail,
HostPassword = _hostPassword, HostPassword = _hostPassword,
@ -218,8 +176,6 @@
IsNewTenant = true, IsNewTenant = true,
SiteName = Constants.DefaultSite SiteName = Constants.DefaultSite
}; };
var installation = await InstallationService.Install(config); var installation = await InstallationService.Install(config);
if (installation.Success) if (installation.Success)

View File

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using MySql.EntityFrameworkCore.Metadata;
using Oqtane.Interfaces;
using Oqtane.Models;
namespace Oqtane.Database.MySQL
{
public class MySQLDatabase : IOqtaneDatabase
{
public MySQLDatabase()
{
ConnectionStringFields = new List<ConnectionStringField>()
{
new() {Name = "Server", FriendlyName = "Server", Value = "127.0.0.1"},
new() {Name = "Port", FriendlyName = "Port", Value = "3306"},
new() {Name = "Database", FriendlyName = "Database", Value = "Oqtane-{{Date}}"},
new() {Name = "Uid", FriendlyName = "User Id", Value = ""},
new() {Name = "Pwd", FriendlyName = "Password", Value = ""}
};
}
public string FriendlyName => Name;
public string Name => "MySQL";
public string Provider => "MySql.EntityFrameworkCore";
public List<ConnectionStringField> ConnectionStringFields { get; }
public OperationBuilder<AddColumnOperation> AddAutoIncrementColumn(ColumnsBuilder table, string name)
{
return table.Column<int>(name: name, nullable: false).Annotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.IdentityColumn);
}
public string BuildConnectionString()
{
var connectionString = String.Empty;
var server = ConnectionStringFields[0].Value;
var port = ConnectionStringFields[1].Value;
var database = ConnectionStringFields[2].Value;
var userId = ConnectionStringFields[3].Value;
var password = ConnectionStringFields[4].Value;
if (!String.IsNullOrEmpty(server) && !String.IsNullOrEmpty(database) && !String.IsNullOrEmpty(userId) && !String.IsNullOrEmpty(password))
{
connectionString = $"Server={server};Database={database};Uid={userId};Pwd={password};";
}
if (!String.IsNullOrEmpty(port))
{
connectionString += $"Port={port};";
}
return connectionString;
}
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString)
{
return optionsBuilder.UseMySQL(connectionString);
}
}
}

View File

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>9</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySql.EntityFrameworkCore" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<LangVersion>9</LangVersion>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EFCore.NamingConventions" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.4" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Models;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Oqtane.Database.PostgreSQL
{
public class PostgreSQLDatabase : IOqtaneDatabase
{
public PostgreSQLDatabase()
{
ConnectionStringFields = new List<ConnectionStringField>()
{
new() {Name = "Server", FriendlyName = "Server", Value = "127.0.0.1"},
new() {Name = "Port", FriendlyName = "Port", Value = "5432"},
new() {Name = "Database", FriendlyName = "Database", Value = "Oqtane-{{Date}}"},
new() {Name = "IntegratedSecurity", FriendlyName = "Integrated Security", Value = "true"},
new() {Name = "Uid", FriendlyName = "User Id", Value = ""},
new() {Name = "Pwd", FriendlyName = "Password", Value = ""}
};
}
public string FriendlyName => Name;
public string Name => "PostgreSQL";
public string Provider => "Npgsql.EntityFrameworkCore.PostgreSQL";
public List<ConnectionStringField> ConnectionStringFields { get; }
public OperationBuilder<AddColumnOperation> AddAutoIncrementColumn(ColumnsBuilder table, string name)
{
return table.Column<int>(name: name, nullable: false).Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityAlwaysColumn);
}
public string BuildConnectionString()
{
var connectionString = String.Empty;
var server = ConnectionStringFields[0].Value;
var port = ConnectionStringFields[1].Value;
var database = ConnectionStringFields[2].Value;
var integratedSecurity = Boolean.Parse(ConnectionStringFields[3].Value);
var userId = ConnectionStringFields[4].Value;
var password = ConnectionStringFields[5].Value;
if (!String.IsNullOrEmpty(server) && !String.IsNullOrEmpty(database) && !String.IsNullOrEmpty(port))
{
connectionString = $"Server={server};Port={port};Database={database};";
}
if (integratedSecurity)
{
connectionString += "Integrated Security=true;";
}
else
{
if (!String.IsNullOrEmpty(userId) && !String.IsNullOrEmpty(password))
{
connectionString += $"User ID={userId};Password={password};";
}
else
{
connectionString = String.Empty;
}
}
return connectionString;
}
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString)
{
return optionsBuilder.UseNpgsql(connectionString).UseSnakeCaseNamingConvention();
}
}
}

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Models;
namespace Oqtane.Repository.Databases
{
public class SqliteDatabase : IOqtaneDatabase
{
public SqliteDatabase()
{
ConnectionStringFields = new List<ConnectionStringField>()
{
new() {Name = "Server", FriendlyName = "File Name", Value = "Oqtane-{{Date}}.db"}
};
}
public string FriendlyName => Name;
public string Name => "Sqlite";
public string Provider => "Microsoft.EntityFrameworkCore.Sqlite";
public List<ConnectionStringField> ConnectionStringFields { get; }
public OperationBuilder<AddColumnOperation> AddAutoIncrementColumn(ColumnsBuilder table, string name)
{
return table.Column<int>(name: name, nullable: false).Annotation("Sqlite:Autoincrement", true);
}
public string BuildConnectionString()
{
var connectionstring = String.Empty;
var server = ConnectionStringFields[0].Value;
if (!String.IsNullOrEmpty(server))
{
connectionstring = $"Data Source={server};";
}
return connectionstring;
}
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString)
{
return optionsBuilder.UseSqlite(connectionString);
}
}
}

View File

@ -0,0 +1,10 @@
using System.Collections.Generic;
using Oqtane.Interfaces;
namespace Oqtane.Repository.Databases.Interfaces
{
public interface IMultiDatabase
{
public IEnumerable<IOqtaneDatabase> Databases { get; }
}
}

View File

@ -1,16 +1,36 @@
using Microsoft.EntityFrameworkCore; using System;
using Oqtane.Interfaces; using System.Collections.Generic;
using Oqtane.Models;
using Oqtane.Repository.Databases;
namespace Oqtane.Repository.Databases namespace Oqtane.Databases
{ {
public class LocalDbDatabase : IDatabase public class LocalDbDatabase : SqlServerDatabaseBase
{ {
public string FriendlyName => "Local Database"; private static string _friendlyName => "Local Database";
public string Name => "LocalDB"; private static string _name => "LocalDB";
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString) private static readonly List<ConnectionStringField> _connectionStringFields = new()
{ {
return optionsBuilder.UseSqlServer(connectionString); new() {Name = "Server", FriendlyName = "Server", Value = "(LocalDb)\\MSSQLLocalDB"},
new() {Name = "Database", FriendlyName = "Database", Value = "Oqtane-{{Date}}"}
};
public LocalDbDatabase() :base(_name, _friendlyName, _connectionStringFields) { }
public override string BuildConnectionString()
{
var connectionString = String.Empty;
var server = ConnectionStringFields[0].Value;
var database = ConnectionStringFields[1].Value;
if (!String.IsNullOrEmpty(server) && !String.IsNullOrEmpty(database))
{
connectionString = $"Data Source={server};AttachDbFilename=|DataDirectory|\\{database}.mdf;Initial Catalog={database};Integrated Security=SSPI;";
}
return connectionString;
} }
} }
} }

View File

@ -1,17 +1,61 @@
using Microsoft.EntityFrameworkCore; using System;
using Oqtane.Interfaces; using System.Collections.Generic;
using Oqtane.Models;
using Oqtane.Repository.Databases;
namespace Oqtane.Repository.Databases // ReSharper disable ArrangeObjectCreationWhenTypeNotEvident
namespace Oqtane.Databases
{ {
public class SqlServerDatabase : IDatabase public class SqlServerDatabase : SqlServerDatabaseBase
{ {
public string FriendlyName => "SQL Server"; private static string _friendlyName => "SQL Server";
private static string _name => "SqlServer";
public string Name => "SqlServer"; private static readonly List<ConnectionStringField> _connectionStringFields = new()
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString)
{ {
return optionsBuilder.UseSqlServer(connectionString); new() {Name = "Server", FriendlyName = "Server", Value = "."},
new() {Name = "Database", FriendlyName = "Database", Value = "Oqtane-{{Date}}"},
new() {Name = "IntegratedSecurity", FriendlyName = "Integrated Security", Value = "true"},
new() {Name = "Uid", FriendlyName = "User Id", Value = ""},
new() {Name = "Pwd", FriendlyName = "Password", Value = ""}
};
public SqlServerDatabase() :base(_name, _friendlyName, _connectionStringFields) { }
public override string BuildConnectionString()
{
var connectionString = String.Empty;
var server = ConnectionStringFields[0].Value;
var database = ConnectionStringFields[1].Value;
var integratedSecurity = Boolean.Parse(ConnectionStringFields[2].Value);
var userId = ConnectionStringFields[3].Value;
var password = ConnectionStringFields[4].Value;
if (!String.IsNullOrEmpty(server) && !String.IsNullOrEmpty(database))
{
connectionString = $"Data Source={server};Initial Catalog={database};";
}
if (integratedSecurity)
{
connectionString += "Integrated Security=SSPI;";
}
else
{
if (!String.IsNullOrEmpty(userId) && !String.IsNullOrEmpty(password))
{
connectionString += $"User ID={userId};Password={password};";
}
else
{
connectionString = String.Empty;
}
}
return connectionString;
} }
} }
} }

View File

@ -0,0 +1,39 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Models;
namespace Oqtane.Repository.Databases
{
public abstract class SqlServerDatabaseBase : IOqtaneDatabase
{
protected SqlServerDatabaseBase(string name, string friendlyName, List<ConnectionStringField> connectionStringFields)
{
Name = name;
FriendlyName = friendlyName;
ConnectionStringFields = connectionStringFields;
}
public string FriendlyName { get; }
public string Name { get; }
public string Provider => "Microsoft.EntityFrameworkCore.SqlServer";
public List<ConnectionStringField> ConnectionStringFields { get; }
public OperationBuilder<AddColumnOperation> AddAutoIncrementColumn(ColumnsBuilder table, string name)
{
return table.Column<int>(name: name, nullable: false).Annotation("SqlServer:Identity", "1, 1");
}
public abstract string BuildConnectionString();
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString)
{
return optionsBuilder.UseSqlServer(connectionString);
}
}
}

View File

@ -1,17 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Oqtane.Interfaces;
namespace Oqtane.Repository.Databases
{
public class SqliteDatabase : IDatabase
{
public string FriendlyName => Name;
public string Name => "Sqlite";
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString)
{
return optionsBuilder.UseSqlite(connectionString);
}
}
}

View File

@ -1,8 +1,6 @@
using System; using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Oqtane.Interfaces; using Oqtane.Interfaces;
// ReSharper disable ConvertToUsingDeclaration // ReSharper disable ConvertToUsingDeclaration
@ -10,14 +8,22 @@ namespace Oqtane.Extensions
{ {
public static class DbContextOptionsBuilderExtensions public static class DbContextOptionsBuilderExtensions
{ {
public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, IOqtaneDatabase database, string connectionString)
{
database.UseDatabase(optionsBuilder, connectionString);
return optionsBuilder;
}
public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, string databaseType, string connectionString) public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, string databaseType, string connectionString)
{ {
var type = Type.GetType(databaseType); var type = Type.GetType(databaseType);
var database = Activator.CreateInstance(type) as IDatabase; var database = Activator.CreateInstance(type) as IOqtaneDatabase;
database.UseDatabase(optionsBuilder, connectionString); database.UseDatabase(optionsBuilder, connectionString);
return optionsBuilder; return optionsBuilder;
} }
} }
} }

View File

@ -48,12 +48,12 @@ namespace Microsoft.Extensions.DependencyInjection
} }
// dynamically register database providers // dynamically register database providers
var databaseTypes = assembly.GetInterfaces<IDatabase>(); var databaseTypes = assembly.GetInterfaces<IOqtaneDatabase>();
foreach (var databaseType in databaseTypes) foreach (var databaseType in databaseTypes)
{ {
if (databaseType.AssemblyQualifiedName != null) if (databaseType.AssemblyQualifiedName != null)
{ {
var serviceType = Type.GetType("Oqtane.Interfaces.IDatabase, Oqtane.Shared"); var serviceType = Type.GetType("Oqtane.Interfaces.IOqtaneDatabase, Oqtane.Shared");
services.AddScoped(serviceType ?? databaseType, databaseType); services.AddScoped(serviceType ?? databaseType, databaseType);
} }
} }

View File

@ -13,6 +13,7 @@ using Oqtane.Models;
using Oqtane.Repository; using Oqtane.Repository;
using Oqtane.Shared; using Oqtane.Shared;
using Oqtane.Enums; using Oqtane.Enums;
using Oqtane.Interfaces;
using File = System.IO.File; using File = System.IO.File;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -172,11 +173,16 @@ namespace Oqtane.Infrastructure
var connectionString = NormalizeConnectionString(install.ConnectionString); var connectionString = NormalizeConnectionString(install.ConnectionString);
var databaseType = install.DatabaseType; var databaseType = install.DatabaseType;
using (var dbc = new DbContext(new DbContextOptionsBuilder().UseOqtaneDatabase(databaseType, connectionString).Options)) using (var scope = _serviceScopeFactory.CreateScope())
{ {
// create empty database if it does not exist var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
dbc.Database.EnsureCreated();
result.Success = true; using (var dbc = new DbContext(new DbContextOptionsBuilder().UseOqtaneDatabase(databases.Single(d => d.Name == databaseType), connectionString).Options))
{
// create empty database if it does not exist
dbc.Database.EnsureCreated();
result.Success = true;
}
} }
} }
catch (Exception ex) catch (Exception ex)
@ -198,26 +204,31 @@ namespace Oqtane.Infrastructure
if (install.TenantName == TenantNames.Master) if (install.TenantName == TenantNames.Master)
{ {
try using (var scope = _serviceScopeFactory.CreateScope())
{ {
var dbConfig = new DbConfig(null, null) {ConnectionString = install.ConnectionString, DatabaseType = install.DatabaseType}; var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
using (var masterDbContext = new MasterDBContext(new DbContextOptions<MasterDBContext>(), dbConfig)) try
{ {
// Push latest model into database var dbConfig = new DbConfig(null, null, databases) {ConnectionString = install.ConnectionString, DatabaseType = install.DatabaseType};
masterDbContext.Database.Migrate();
result.Success = true;
}
}
catch (Exception ex)
{
result.Message = ex.Message;
}
if (result.Success) using (var masterDbContext = new MasterDBContext(new DbContextOptions<MasterDBContext>(), dbConfig))
{ {
UpdateConnectionString(install.ConnectionString); // Push latest model into database
UpdateDatabaseType(install.DatabaseType); masterDbContext.Database.Migrate();
result.Success = true;
}
}
catch (Exception ex)
{
result.Message = ex.Message;
}
if (result.Success)
{
UpdateConnectionString(install.ConnectionString);
UpdateDatabaseType(install.DatabaseType);
}
} }
} }
else else
@ -234,38 +245,56 @@ namespace Oqtane.Infrastructure
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases)) if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases))
{ {
using (var db = GetInstallationContext()) using (var scope = _serviceScopeFactory.CreateScope())
{ {
Tenant tenant; var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
if (install.IsNewTenant)
{
tenant = new Tenant { Name = install.TenantName,
DBConnectionString = DenormalizeConnectionString(install.ConnectionString),
DBType = install.DatabaseType,
CreatedBy = "",
CreatedOn = DateTime.UtcNow,
ModifiedBy = "",
ModifiedOn = DateTime.UtcNow };
db.Tenant.Add(tenant);
db.SaveChanges();
_cache.Remove("tenants");
}
else
{
tenant = db.Tenant.FirstOrDefault(item => item.Name == install.TenantName);
}
foreach (var aliasName in install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) using (var db = GetInstallationContext(databases))
{ {
if (tenant != null) Tenant tenant;
if (install.IsNewTenant)
{ {
var alias = new Alias { Name = aliasName, TenantId = tenant.TenantId, SiteId = -1, CreatedBy = "", CreatedOn = DateTime.UtcNow, ModifiedBy = "", ModifiedOn = DateTime.UtcNow }; tenant = new Tenant
db.Alias.Add(alias); {
Name = install.TenantName,
DBConnectionString = DenormalizeConnectionString(install.ConnectionString),
DBType = install.DatabaseType,
CreatedBy = "",
CreatedOn = DateTime.UtcNow,
ModifiedBy = "",
ModifiedOn = DateTime.UtcNow
};
db.Tenant.Add(tenant);
db.SaveChanges();
_cache.Remove("tenants");
}
else
{
tenant = db.Tenant.FirstOrDefault(item => item.Name == install.TenantName);
} }
db.SaveChanges(); foreach (var aliasName in install.Aliases.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
{
if (tenant != null)
{
var alias = new Alias
{
Name = aliasName,
TenantId = tenant.TenantId,
SiteId = -1,
CreatedBy = "",
CreatedOn = DateTime.UtcNow,
ModifiedBy = "",
ModifiedOn = DateTime.UtcNow
};
db.Alias.Add(alias);
}
db.SaveChanges();
}
_cache.Remove("aliases");
} }
_cache.Remove("aliases");
} }
} }
@ -274,12 +303,12 @@ namespace Oqtane.Infrastructure
return result; return result;
} }
private InstallationContext GetInstallationContext() private InstallationContext GetInstallationContext(IEnumerable<IOqtaneDatabase> databases)
{ {
var databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey]; var databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey];
var connectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey)); var connectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey));
return new InstallationContext(databaseType, connectionString); return new InstallationContext(databases.Single(d => d.Name == databaseType), connectionString);
} }
private Installation MigrateTenants(InstallConfig install) private Installation MigrateTenants(InstallConfig install)
@ -291,14 +320,15 @@ namespace Oqtane.Infrastructure
using (var scope = _serviceScopeFactory.CreateScope()) using (var scope = _serviceScopeFactory.CreateScope())
{ {
var upgrades = scope.ServiceProvider.GetRequiredService<IUpgradeManager>(); var upgrades = scope.ServiceProvider.GetRequiredService<IUpgradeManager>();
var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
using (var db = GetInstallationContext()) using (var db = GetInstallationContext(databases))
{ {
foreach (var tenant in db.Tenant.ToList()) foreach (var tenant in db.Tenant.ToList())
{ {
try try
{ {
var dbConfig = new DbConfig(null, null) {ConnectionString = install.ConnectionString, DatabaseType = install.DatabaseType}; var dbConfig = new DbConfig(null, null, databases) {ConnectionString = install.ConnectionString, DatabaseType = install.DatabaseType};
using (var tenantDbContext = new TenantDBContext(dbConfig, null)) using (var tenantDbContext = new TenantDBContext(dbConfig, null))
{ {
// Push latest model into database // Push latest model into database
@ -345,6 +375,8 @@ namespace Oqtane.Infrastructure
{ {
var moduleDefinitions = scope.ServiceProvider.GetRequiredService<IModuleDefinitionRepository>(); var moduleDefinitions = scope.ServiceProvider.GetRequiredService<IModuleDefinitionRepository>();
var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>(); var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>();
var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
foreach (var moduleDefinition in moduleDefinitions.GetModuleDefinitions()) foreach (var moduleDefinition in moduleDefinitions.GetModuleDefinitions())
{ {
if (!string.IsNullOrEmpty(moduleDefinition.ReleaseVersions) && !string.IsNullOrEmpty(moduleDefinition.ServerManagerType)) if (!string.IsNullOrEmpty(moduleDefinition.ReleaseVersions) && !string.IsNullOrEmpty(moduleDefinition.ServerManagerType))
@ -353,7 +385,7 @@ namespace Oqtane.Infrastructure
if (moduleType != null) if (moduleType != null)
{ {
var versions = moduleDefinition.ReleaseVersions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var versions = moduleDefinition.ReleaseVersions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
using (var db = GetInstallationContext()) using (var db = GetInstallationContext(databases))
{ {
foreach (var tenant in db.Tenant.ToList()) foreach (var tenant in db.Tenant.ToList())
{ {

View File

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
using Oqtane.Repository; using Oqtane.Repository;
@ -9,52 +11,57 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(MasterDBContext))] [DbContext(typeof(MasterDBContext))]
[Migration("Master.01.00.00.00")] [Migration("Master.01.00.00.00")]
public class InitializeMaster : Migration public class InitializeMaster : MultiDatabaseMigration
{ {
public InitializeMaster(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Create Tenant table //Create Tenant table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder); var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.Create(); tenantEntityBuilder.Create();
//Create Alias table //Create Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder); var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.Create(); aliasEntityBuilder.Create();
//Create ModuleDefinitions Table //Create ModuleDefinitions Table
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder); var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder, ActiveDatabase);
moduleDefinitionsEntityBuilder.Create(); moduleDefinitionsEntityBuilder.Create();
//Create Job Table //Create Job Table
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder); var jobEntityBuilder = new JobEntityBuilder(migrationBuilder, ActiveDatabase);
jobEntityBuilder.Create(); jobEntityBuilder.Create();
//Create JobLog Table //Create JobLog Table
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder); var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder, ActiveDatabase);
jobLogEntityBuilder.Create(); jobLogEntityBuilder.Create();
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Drop Alias table //Drop Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder); var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.Drop(); aliasEntityBuilder.Drop();
//Drop JobLog Table //Drop JobLog Table
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder); var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder, ActiveDatabase);
jobLogEntityBuilder.Drop(); jobLogEntityBuilder.Drop();
//Drop Tenant table //Drop Tenant table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder); var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.Drop(); tenantEntityBuilder.Drop();
//Drop ModuleDefinitions Table //Drop ModuleDefinitions Table
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder); var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder, ActiveDatabase);
moduleDefinitionsEntityBuilder.Drop(); moduleDefinitionsEntityBuilder.Drop();
//Drop Job Table //Drop Job Table
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder); var jobEntityBuilder = new JobEntityBuilder(migrationBuilder, ActiveDatabase);
jobEntityBuilder.Drop(); jobEntityBuilder.Drop();
} }
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository; using Oqtane.Repository;
@ -8,86 +10,90 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(TenantDBContext))] [DbContext(typeof(TenantDBContext))]
[Migration("Tenant.01.00.00.00")] [Migration("Tenant.01.00.00.00")]
public class InitializeTenant : Migration public class InitializeTenant : MultiDatabaseMigration
{ {
public InitializeTenant(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Create Site table //Create Site table
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder); var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.Create(); siteEntityBuilder.Create();
//Create Page table //Create Page table
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder); var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
pageEntityBuilder.Create(); pageEntityBuilder.Create();
pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true); pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true);
//Add Column to Page table (for Sql Server only) we will drop it later for Sql Server only //Add Column to Page table (for Sql Server only) we will drop it later for Sql Server only
if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.SqlServer") if (ActiveDatabase.Name == "SqlServer" || ActiveDatabase.Name == "LocalDB")
{ {
pageEntityBuilder.AddBooleanColumn("EditMode"); pageEntityBuilder.AddBooleanColumn("EditMode");
} }
//Create Module table //Create Module table
var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder); var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder, ActiveDatabase);
moduleEntityBuilder.Create(); moduleEntityBuilder.Create();
//Create PageModule table //Create PageModule table
var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder); var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder, ActiveDatabase);
pageModuleEntityBuilder.Create(); pageModuleEntityBuilder.Create();
//Create User table //Create User table
var userEntityBuilder = new UserEntityBuilder(migrationBuilder); var userEntityBuilder = new UserEntityBuilder(migrationBuilder, ActiveDatabase);
userEntityBuilder.Create(); userEntityBuilder.Create();
userEntityBuilder.AddIndex("IX_User", "Username", true); userEntityBuilder.AddIndex("IX_User", "Username", true);
//Create Role table //Create Role table
var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder); var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder, ActiveDatabase);
roleEntityBuilder.Create(); roleEntityBuilder.Create();
//Create UserRole table //Create UserRole table
var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder); var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder, ActiveDatabase);
userRoleEntityBuilder.Create(); userRoleEntityBuilder.Create();
userRoleEntityBuilder.AddIndex("IX_UserRole", new [] {"RoleId", "UserId"}, true); userRoleEntityBuilder.AddIndex("IX_UserRole", new [] {"RoleId", "UserId"}, true);
//Create Permission table //Create Permission table
var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder); var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder, ActiveDatabase);
permissionEntityBuilder.Create(); permissionEntityBuilder.Create();
permissionEntityBuilder.AddIndex("IX_Permission", new [] {"SiteId", "EntityName", "EntityId", "PermissionName", "RoleId", "UserId"}, true); permissionEntityBuilder.AddIndex("IX_Permission", new [] {"SiteId", "EntityName", "EntityId", "PermissionName", "RoleId", "UserId"}, true);
//Create Setting table //Create Setting table
var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder); var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder, ActiveDatabase);
settingEntityBuilder.Create(); settingEntityBuilder.Create();
settingEntityBuilder.AddIndex("IX_Setting", new [] {"EntityName", "EntityId", "SettingName"}, true); settingEntityBuilder.AddIndex("IX_Setting", new [] {"EntityName", "EntityId", "SettingName"}, true);
//Create Profile table //Create Profile table
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder); var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
profileEntityBuilder.Create(); profileEntityBuilder.Create();
//Create Log table //Create Log table
var logEntityBuilder = new LogEntityBuilder(migrationBuilder); var logEntityBuilder = new LogEntityBuilder(migrationBuilder, ActiveDatabase);
logEntityBuilder.Create(); logEntityBuilder.Create();
//Create Notification table //Create Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder); var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.Create(); notificationEntityBuilder.Create();
//Create Folder table //Create Folder table
var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder); var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder, ActiveDatabase);
folderEntityBuilder.Create(); folderEntityBuilder.Create();
folderEntityBuilder.AddIndex("IX_Folder", new [] {"SiteId", "Path"}, true); folderEntityBuilder.AddIndex("IX_Folder", new [] {"SiteId", "Path"}, true);
//Create File table //Create File table
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder); var fileEntityBuilder = new FileEntityBuilder(migrationBuilder, ActiveDatabase);
fileEntityBuilder.Create(); fileEntityBuilder.Create();
//Create AspNetUsers table //Create AspNetUsers table
var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder); var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder, ActiveDatabase);
aspNetUsersEntityBuilder.Create(); aspNetUsersEntityBuilder.Create();
aspNetUsersEntityBuilder.AddIndex("EmailIndex", "NormalizedEmail", true); aspNetUsersEntityBuilder.AddIndex("EmailIndex", "NormalizedEmail", true);
aspNetUsersEntityBuilder.AddIndex("UserNameIndex", "NormalizedUserName", true); aspNetUsersEntityBuilder.AddIndex("UserNameIndex", "NormalizedUserName", true);
//Create AspNetUserClaims table //Create AspNetUserClaims table
var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder); var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder, ActiveDatabase);
aspNetUserClaimsEntityBuilder.Create(); aspNetUserClaimsEntityBuilder.Create();
aspNetUserClaimsEntityBuilder.AddIndex("IX_AspNetUserClaims_UserId", "UserId", true); aspNetUserClaimsEntityBuilder.AddIndex("IX_AspNetUserClaims_UserId", "UserId", true);
@ -96,67 +102,67 @@ namespace Oqtane.Migrations
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Drop AspNetUserClaims table //Drop AspNetUserClaims table
var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder); var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder, ActiveDatabase);
aspNetUserClaimsEntityBuilder.Drop(); aspNetUserClaimsEntityBuilder.Drop();
//Drop AspNetUsers table //Drop AspNetUsers table
var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder); var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder, ActiveDatabase);
aspNetUsersEntityBuilder.Drop(); aspNetUsersEntityBuilder.Drop();
//Drop File table //Drop File table
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder); var fileEntityBuilder = new FileEntityBuilder(migrationBuilder, ActiveDatabase);
fileEntityBuilder.Drop(); fileEntityBuilder.Drop();
//Drop Folder table //Drop Folder table
var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder); var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder, ActiveDatabase);
folderEntityBuilder.Drop(); folderEntityBuilder.Drop();
//Drop Notification table //Drop Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder); var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.Drop(); notificationEntityBuilder.Drop();
//Drop Log table //Drop Log table
var logEntityBuilder = new LogEntityBuilder(migrationBuilder); var logEntityBuilder = new LogEntityBuilder(migrationBuilder, ActiveDatabase);
logEntityBuilder.Drop(); logEntityBuilder.Drop();
//Drop Profile table //Drop Profile table
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder); var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
profileEntityBuilder.Drop(); profileEntityBuilder.Drop();
//Drop Setting table //Drop Setting table
var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder); var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder, ActiveDatabase);
settingEntityBuilder.Drop(); settingEntityBuilder.Drop();
//Drop Permission table //Drop Permission table
var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder); var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder, ActiveDatabase);
permissionEntityBuilder.Drop(); permissionEntityBuilder.Drop();
//Drop UserRole table //Drop UserRole table
var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder); var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder, ActiveDatabase);
userRoleEntityBuilder.Drop(); userRoleEntityBuilder.Drop();
//Drop Role table //Drop Role table
var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder); var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder, ActiveDatabase);
roleEntityBuilder.Drop(); roleEntityBuilder.Drop();
//Drop User table //Drop User table
var userEntityBuilder = new UserEntityBuilder(migrationBuilder); var userEntityBuilder = new UserEntityBuilder(migrationBuilder, ActiveDatabase);
userEntityBuilder.Drop(); userEntityBuilder.Drop();
//Drop PageModule table //Drop PageModule table
var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder); var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder, ActiveDatabase);
pageModuleEntityBuilder.Drop(); pageModuleEntityBuilder.Drop();
//Drop Module table //Drop Module table
var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder); var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder, ActiveDatabase);
moduleEntityBuilder.Drop(); moduleEntityBuilder.Drop();
//Drop Page table //Drop Page table
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder); var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
pageEntityBuilder.Drop(); pageEntityBuilder.Drop();
//Drop Site table //Drop Site table
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder); var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.Drop(); siteEntityBuilder.Drop();
} }
} }

View File

@ -1,5 +1,7 @@
using Microsoft.EntityFrameworkCore.Infrastructure; using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository; using Oqtane.Repository;
@ -7,43 +9,47 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(MasterDBContext))] [DbContext(typeof(MasterDBContext))]
[Migration("Master.01.00.01.00")] [Migration("Master.01.00.01.00")]
public class AddAdditionalIndexesInMaster : Migration public class AddAdditionalIndexesInMaster : MultiDatabaseMigration
{ {
public AddAdditionalIndexesInMaster(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Update Tenant table //Update Tenant table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder); var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.AddIndex("IX_Tenant", "Name"); tenantEntityBuilder.AddIndex("IX_Tenant", "Name");
//Update Alias table //Update Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder); var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.AddIndex("IX_Alias", "Name"); aliasEntityBuilder.AddIndex("IX_Alias", "Name");
//Update ModuleDefinitions Table //Update ModuleDefinitions Table
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder); var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder, ActiveDatabase);
moduleDefinitionsEntityBuilder.AddIndex("IX_ModuleDefinition", "ModuleDefinitionName"); moduleDefinitionsEntityBuilder.AddIndex("IX_ModuleDefinition", "ModuleDefinitionName");
//Update Job Table //Update Job Table
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder); var jobEntityBuilder = new JobEntityBuilder(migrationBuilder, ActiveDatabase);
jobEntityBuilder.AddIndex("IX_Job", "JobType"); jobEntityBuilder.AddIndex("IX_Job", "JobType");
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Update Tenant table //Update Tenant table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder); var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.DropIndex("IX_Tenant"); tenantEntityBuilder.DropIndex("IX_Tenant");
//Update Alias table //Update Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder); var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.DropIndex("IX_Alias"); aliasEntityBuilder.DropIndex("IX_Alias");
//Update ModuleDefinitions Table //Update ModuleDefinitions Table
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder); var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder, ActiveDatabase);
moduleDefinitionsEntityBuilder.DropIndex("IX_ModuleDefinition"); moduleDefinitionsEntityBuilder.DropIndex("IX_ModuleDefinition");
//Update Job Table //Update Job Table
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder); var jobEntityBuilder = new JobEntityBuilder(migrationBuilder, ActiveDatabase);
jobEntityBuilder.DropIndex("IX_Job"); jobEntityBuilder.DropIndex("IX_Job");
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
using Oqtane.Repository; using Oqtane.Repository;
@ -8,28 +10,32 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(TenantDBContext))] [DbContext(typeof(TenantDBContext))]
[Migration("Tenant.01.00.01.00")] [Migration("Tenant.01.00.01.00")]
public class AddAdditionalIndexesInTenant : Migration public class AddAdditionalIndexesInTenant : MultiDatabaseMigration
{ {
public AddAdditionalIndexesInTenant(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Create Index on Site //Create Index on Site
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder); var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.AddIndex("IX_Site", new [] {"TenantId", "Name"}, true); siteEntityBuilder.AddIndex("IX_Site", new [] {"TenantId", "Name"}, true);
//Create Index on Role table //Create Index on Role table
var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder); var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder, ActiveDatabase);
roleEntityBuilder.AddIndex("IX_Role", new [] {"SiteId", "Name"}, true); roleEntityBuilder.AddIndex("IX_Role", new [] {"SiteId", "Name"}, true);
//Create Index on Profile table //Create Index on Profile table
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder); var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
profileEntityBuilder.AddIndex("IX_Profile", new [] {"SiteId", "Name"}, true); profileEntityBuilder.AddIndex("IX_Profile", new [] {"SiteId", "Name"}, true);
//Create Index on File table //Create Index on File table
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder); var fileEntityBuilder = new FileEntityBuilder(migrationBuilder, ActiveDatabase);
fileEntityBuilder.AddIndex("IX_File", new [] {"FolderId", "Name"}, true); fileEntityBuilder.AddIndex("IX_File", new [] {"FolderId", "Name"}, true);
//Add Columns to Notification table //Add Columns to Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder); var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.AddStringColumn("FromDisplayName", 50, true); notificationEntityBuilder.AddStringColumn("FromDisplayName", 50, true);
notificationEntityBuilder.AddStringColumn("FromEmail", 256, true); notificationEntityBuilder.AddStringColumn("FromEmail", 256, true);
notificationEntityBuilder.AddStringColumn("ToDisplayName", 50, true); notificationEntityBuilder.AddStringColumn("ToDisplayName", 50, true);
@ -38,27 +44,26 @@ namespace Oqtane.Migrations
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Drop Index on Site table //Drop Index on Site table
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder); var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.DropIndex("IX_Site"); siteEntityBuilder.DropIndex("IX_Site");
//Drop Index on Role table //Drop Index on Role table
var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder); var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder, ActiveDatabase);
roleEntityBuilder.DropIndex("IX_Role"); roleEntityBuilder.DropIndex("IX_Role");
//Drop Index on Profile table //Drop Index on Profile table
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder); var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
profileEntityBuilder.DropIndex("IX_Profile"); profileEntityBuilder.DropIndex("IX_Profile");
//Drop Index on File table //Drop Index on File table
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder); var fileEntityBuilder = new FileEntityBuilder(migrationBuilder, ActiveDatabase);
fileEntityBuilder.DropIndex("IX_File"); fileEntityBuilder.DropIndex("IX_File");
//Drop Columns from Notification table //Drop Columns from Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder); var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.DropColumn("FromDisplayName"); notificationEntityBuilder.DropColumn("FromDisplayName");
notificationEntityBuilder.DropColumn("FromEmail"); notificationEntityBuilder.DropColumn("FromEmail");
notificationEntityBuilder.DropColumn("ToDisplayName"); notificationEntityBuilder.DropColumn("ToDisplayName");
} }
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository; using Oqtane.Repository;
@ -7,12 +9,16 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(TenantDBContext))] [DbContext(typeof(TenantDBContext))]
[Migration("Tenant.01.00.01.01")] [Migration("Tenant.01.00.01.01")]
public class AddAdditionColumnToNotifications : Migration public class AddAdditionColumnToNotifications : MultiDatabaseMigration
{ {
public AddAdditionColumnToNotifications(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Add Column to Notification table //Add Column to Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder); var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.AddDateTimeColumn("SendOn", true); notificationEntityBuilder.AddDateTimeColumn("SendOn", true);
migrationBuilder.Sql( migrationBuilder.Sql(
@ -26,7 +32,7 @@ namespace Oqtane.Migrations
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Drop Column from Notification table //Drop Column from Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder); var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.DropColumn("SendOn"); notificationEntityBuilder.DropColumn("SendOn");
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository; using Oqtane.Repository;
@ -7,14 +9,18 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(TenantDBContext))] [DbContext(typeof(TenantDBContext))]
[Migration("Tenant.01.00.02.01")] [Migration("Tenant.01.00.02.01")]
public class DropColumnFromPage : Migration public class DropColumnFromPage : MultiDatabaseMigration
{ {
public DropColumnFromPage(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Drop Column from Page table //Drop Column from Page table
if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.SqlServer") if (ActiveDatabase.Name == "SqlServer" || ActiveDatabase.Name == "LocalDB")
{ {
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder); var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
pageEntityBuilder.DropColumn("EditMode"); pageEntityBuilder.DropColumn("EditMode");
} }
} }
@ -22,7 +28,7 @@ namespace Oqtane.Migrations
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Add Column to Page table //Add Column to Page table
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder); var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
pageEntityBuilder.AddBooleanColumn("EditMode"); pageEntityBuilder.AddBooleanColumn("EditMode");
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository; using Oqtane.Repository;
@ -7,25 +9,28 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(TenantDBContext))] [DbContext(typeof(TenantDBContext))]
[Migration("Tenant.02.00.00.01")] [Migration("Tenant.02.00.00.01")]
public class AddColumnToProfileAndUpdatePage : Migration public class AddColumnToProfileAndUpdatePage : MultiDatabaseMigration
{ {
public AddColumnToProfileAndUpdatePage(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Add Column to Profile table //Add Column to Profile table
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder); var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
profileEntityBuilder.AddStringColumn("Options", 2000, true); profileEntityBuilder.AddStringColumn("Options", 2000, true);
///Update new field
migrationBuilder.Sql( migrationBuilder.Sql(
@" @"
UPDATE Profile UPDATE Profile
SET Options = '' SET Options = ''
"); ");
//Alter Column in Page table //Alter Column in Page table for Sql Server
if (migrationBuilder.ActiveProvider != "Microsoft.EntityFrameworkCore.Sqlite") if (ActiveDatabase.Name == "SqlServer" || ActiveDatabase.Name == "LocalDB")
{ {
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder); var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
pageEntityBuilder.DropIndex("IX_Page"); pageEntityBuilder.DropIndex("IX_Page");
pageEntityBuilder.AlterStringColumn("Path", 256); pageEntityBuilder.AlterStringColumn("Path", 256);
pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true); pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true);
@ -35,13 +40,13 @@ namespace Oqtane.Migrations
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Drop Column from Profile table //Drop Column from Profile table
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder); var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
profileEntityBuilder.DropColumn("Options"); profileEntityBuilder.DropColumn("Options");
//Alter Column in Page table //Alter Column in Page table
if (migrationBuilder.ActiveProvider != "Microsoft.EntityFrameworkCore.Sqlite") if (ActiveDatabase.Name == "SqlServer" || ActiveDatabase.Name == "LocalDB")
{ {
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder); var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
pageEntityBuilder.DropIndex("IX_Page"); pageEntityBuilder.DropIndex("IX_Page");
pageEntityBuilder.AlterStringColumn("Path", 50); pageEntityBuilder.AlterStringColumn("Path", 50);
pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true); pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true);

View File

@ -1,20 +1,27 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Repository; using Oqtane.Repository;
namespace Oqtane.Migrations namespace Oqtane.Migrations
{ {
[DbContext(typeof(TenantDBContext))] [DbContext(typeof(TenantDBContext))]
[Migration("Tenant.02.00.01.01")] [Migration("Tenant.02.00.01.01")]
public class UpdateIconColumnInPage : Migration public class UpdateIconColumnInPage : MultiDatabaseMigration
{ {
public UpdateIconColumnInPage(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
///Update Icon Field in Page ///Update Icon Field in Page
migrationBuilder.Sql( migrationBuilder.Sql(
@" @"
UPDATE [Page] UPDATE Page
SET Icon = IIF(Icon <> '', 'oi oi-' + Icon, ''); SET Icon = 'oi oi-' + Icon
WHERE Icon <> ''
"); ");
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository; using Oqtane.Repository;
@ -7,19 +9,23 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(TenantDBContext))] [DbContext(typeof(TenantDBContext))]
[Migration("Tenant.02.00.01.02")] [Migration("Tenant.02.00.01.02")]
public class AddLanguageTable : Migration public class AddLanguageTable : MultiDatabaseMigration
{ {
public AddLanguageTable(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Create Language table //Create Language table
var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder); var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder, ActiveDatabase);
languageEntityBuilder.Create(); languageEntityBuilder.Create();
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Drop Language table //Drop Language table
var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder); var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder, ActiveDatabase);
languageEntityBuilder.Drop(); languageEntityBuilder.Drop();
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository; using Oqtane.Repository;
@ -7,12 +9,16 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(TenantDBContext))] [DbContext(typeof(TenantDBContext))]
[Migration("Tenant.02.00.01.03")] [Migration("Tenant.02.00.01.03")]
public class UpdatePageAndAddColumnToSite : Migration public class UpdatePageAndAddColumnToSite : MultiDatabaseMigration
{ {
public UpdatePageAndAddColumnToSite(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Add Column to Site table //Add Column to Site table
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder); var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.AddStringColumn("AdminContainerType", 200, true); siteEntityBuilder.AddStringColumn("AdminContainerType", 200, true);
//Update new column //Update new column
@ -25,8 +31,8 @@ namespace Oqtane.Migrations
//Delete records from Page //Delete records from Page
migrationBuilder.Sql( migrationBuilder.Sql(
@" @"
DELETE FROM [Page] DELETE FROM Page
WHERE Path = 'admin/tenants'; WHERE Path = 'admin/tenants'
"); ");
} }
@ -34,7 +40,7 @@ namespace Oqtane.Migrations
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Drop Column from Site table //Drop Column from Site table
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder); var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.DropColumn("AdminContainerType"); siteEntityBuilder.DropColumn("AdminContainerType");
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository; using Oqtane.Repository;
@ -7,27 +9,31 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(MasterDBContext))] [DbContext(typeof(MasterDBContext))]
[Migration("Master.02.01.00.00")] [Migration("Master.02.01.00.00")]
public class AddIndexesForForeignKeyInMaster : Migration public class AddIndexesForForeignKeyInMaster : MultiDatabaseMigration
{ {
public AddIndexesForForeignKeyInMaster(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Update JobLog table //Update JobLog table
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder); var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder, ActiveDatabase);
jobLogEntityBuilder.AddIndex("IX_JobLog_JobId", "JobId"); jobLogEntityBuilder.AddIndex("IX_JobLog_JobId", "JobId");
//Update Alias table //Update Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder); var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.AddIndex("IX_Alias_TenantId", "TenantId"); aliasEntityBuilder.AddIndex("IX_Alias_TenantId", "TenantId");
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Update JobLog table //Update JobLog table
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder); var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder, ActiveDatabase);
jobLogEntityBuilder.DropIndex("IX_JobLog_JobId"); jobLogEntityBuilder.DropIndex("IX_JobLog_JobId");
//Update Alias table //Update Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder); var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.DropIndex("IX_Alias_TenantId"); aliasEntityBuilder.DropIndex("IX_Alias_TenantId");
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository; using Oqtane.Repository;
@ -7,21 +9,28 @@ namespace Oqtane.Migrations
{ {
[DbContext(typeof(MasterDBContext))] [DbContext(typeof(MasterDBContext))]
[Migration("Master.02.01.00.01")] [Migration("Master.02.01.00.01")]
public class AddDatabaseTypeColumnToTenant : Migration public class AddDatabaseTypeColumnToTenant : MultiDatabaseMigration
{ {
public AddDatabaseTypeColumnToTenant(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Add Column to Site table //Add Column to Site table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder); var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.AddStringColumn("DBType", 200, true); tenantEntityBuilder.AddStringColumn("DBType", 200, true);
//Update new column //Update new column if SqlServer (Other Databases will not have any records yet)
migrationBuilder.Sql( if (ActiveDatabase.Name == "SqlServer" || ActiveDatabase.Name == "LocalDB")
@" {
migrationBuilder.Sql(@"
UPDATE Tenant UPDATE Tenant
SET DBType = 'Oqtane.Repository.Databases.SqlServerDatabase, Oqtane.Server' SET DBType = 'SqlServer'
"); ");
}
} }
} }
} }

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<AliasEntityBuilder> _primaryKey = new("PK_Alias", x => x.AliasId); private readonly PrimaryKey<AliasEntityBuilder> _primaryKey = new("PK_Alias", x => x.AliasId);
private readonly ForeignKey<AliasEntityBuilder> _tenantForeignKey = new("FK_Alias_Tenant", x => x.TenantId, "Tenant", "TenantId", ReferentialAction.Cascade); private readonly ForeignKey<AliasEntityBuilder> _tenantForeignKey = new("FK_Alias_Tenant", x => x.TenantId, "Tenant", "TenantId", ReferentialAction.Cascade);
public AliasEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public AliasEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override AliasEntityBuilder BuildTable(ColumnsBuilder table) protected override AliasEntityBuilder BuildTable(ColumnsBuilder table)
{ {
AliasId = table.AddAutoIncrementColumn("AliasId"); AliasId = ActiveDatabase.AddAutoIncrementColumn(table,"AliasId");
Name = table.AddStringColumn("Name", 200); Name = table.AddStringColumn("Name", 200);
TenantId = table.AddIntegerColumn("TenantId"); TenantId = table.AddIntegerColumn("TenantId");
SiteId = table.AddIntegerColumn("SiteId"); SiteId = table.AddIntegerColumn("SiteId");

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<AspNetUserClaimsEntityBuilder> _primaryKey = new("PK_AspNetUserClaims", x => x.Id); private readonly PrimaryKey<AspNetUserClaimsEntityBuilder> _primaryKey = new("PK_AspNetUserClaims", x => x.Id);
private readonly ForeignKey<AspNetUserClaimsEntityBuilder> _aspNetUsersForeignKey = new("FK_AspNetUserClaims_AspNetUsers_UserId", x => x.UserId, "AspNetUsers", "Id", ReferentialAction.Cascade); private readonly ForeignKey<AspNetUserClaimsEntityBuilder> _aspNetUsersForeignKey = new("FK_AspNetUserClaims_AspNetUsers_UserId", x => x.UserId, "AspNetUsers", "Id", ReferentialAction.Cascade);
public AspNetUserClaimsEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public AspNetUserClaimsEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override AspNetUserClaimsEntityBuilder BuildTable(ColumnsBuilder table) protected override AspNetUserClaimsEntityBuilder BuildTable(ColumnsBuilder table)
{ {
Id = table.AddAutoIncrementColumn("Id"); Id = ActiveDatabase.AddAutoIncrementColumn(table,"Id");
UserId = table.AddStringColumn("UserId", 450); UserId = table.AddStringColumn("UserId", 450);
ClaimType = table.AddMaxStringColumn("ClaimType", true); ClaimType = table.AddMaxStringColumn("ClaimType", true);
ClaimValue = table.AddMaxStringColumn("ClaimValue", true); ClaimValue = table.AddMaxStringColumn("ClaimValue", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "AspNetUsers"; private const string _entityTableName = "AspNetUsers";
private readonly PrimaryKey<AspNetUsersEntityBuilder> _primaryKey = new("PK_AspNetUsers", x => x.Id); private readonly PrimaryKey<AspNetUsersEntityBuilder> _primaryKey = new("PK_AspNetUsers", x => x.Id);
public AspNetUsersEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public AspNetUsersEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable UnusedAutoPropertyAccessor.Global // ReSharper disable UnusedAutoPropertyAccessor.Global
@ -10,7 +11,7 @@ namespace Oqtane.Migrations.EntityBuilders
{ {
public abstract class AuditableBaseEntityBuilder<TEntityBuilder> : BaseEntityBuilder<TEntityBuilder> where TEntityBuilder : BaseEntityBuilder<TEntityBuilder> public abstract class AuditableBaseEntityBuilder<TEntityBuilder> : BaseEntityBuilder<TEntityBuilder> where TEntityBuilder : BaseEntityBuilder<TEntityBuilder>
{ {
protected AuditableBaseEntityBuilder(MigrationBuilder migrationBuilder) : base (migrationBuilder) protected AuditableBaseEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base (migrationBuilder, database)
{ {
} }

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
namespace Oqtane.Migrations.EntityBuilders namespace Oqtane.Migrations.EntityBuilders
@ -10,9 +11,10 @@ namespace Oqtane.Migrations.EntityBuilders
{ {
private readonly MigrationBuilder _migrationBuilder; private readonly MigrationBuilder _migrationBuilder;
protected BaseEntityBuilder(MigrationBuilder migrationBuilder) protected BaseEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database)
{ {
_migrationBuilder = migrationBuilder; _migrationBuilder = migrationBuilder;
ActiveDatabase = database;
ForeignKeys = new List<ForeignKey<TEntityBuilder>>(); ForeignKeys = new List<ForeignKey<TEntityBuilder>>();
} }
@ -23,9 +25,10 @@ namespace Oqtane.Migrations.EntityBuilders
{ {
table.AddForeignKey(foreignKey); table.AddForeignKey(foreignKey);
} }
} }
protected IOqtaneDatabase ActiveDatabase { get; }
protected abstract TEntityBuilder BuildTable(ColumnsBuilder table); protected abstract TEntityBuilder BuildTable(ColumnsBuilder table);
protected string EntityTableName { get; init; } protected string EntityTableName { get; init; }

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable UnusedAutoPropertyAccessor.Global // ReSharper disable UnusedAutoPropertyAccessor.Global
@ -10,7 +11,7 @@ namespace Oqtane.Migrations.EntityBuilders
{ {
public abstract class DeletableAuditableBaseEntityBuilder<TEntityBuilder> : AuditableBaseEntityBuilder<TEntityBuilder> where TEntityBuilder : BaseEntityBuilder<TEntityBuilder> public abstract class DeletableAuditableBaseEntityBuilder<TEntityBuilder> : AuditableBaseEntityBuilder<TEntityBuilder> where TEntityBuilder : BaseEntityBuilder<TEntityBuilder>
{ {
protected DeletableAuditableBaseEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) protected DeletableAuditableBaseEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
} }

View File

@ -2,6 +2,7 @@ using System;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable UnusedAutoPropertyAccessor.Global // ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -10,7 +11,7 @@ namespace Oqtane.Migrations.EntityBuilders
{ {
public abstract class DeletableBaseEntityBuilder<TEntityBuilder> : BaseEntityBuilder<TEntityBuilder> where TEntityBuilder : BaseEntityBuilder<TEntityBuilder> public abstract class DeletableBaseEntityBuilder<TEntityBuilder> : BaseEntityBuilder<TEntityBuilder> where TEntityBuilder : BaseEntityBuilder<TEntityBuilder>
{ {
protected DeletableBaseEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) protected DeletableBaseEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
} }

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<FileEntityBuilder> _primaryKey = new("PK_File", x => x.FileId); private readonly PrimaryKey<FileEntityBuilder> _primaryKey = new("PK_File", x => x.FileId);
private readonly ForeignKey<FileEntityBuilder> _folderForeignKey = new("FK_File_Folder", x => x.FolderId, "Folder", "FolderId", ReferentialAction.Cascade); private readonly ForeignKey<FileEntityBuilder> _folderForeignKey = new("FK_File_Folder", x => x.FolderId, "Folder", "FolderId", ReferentialAction.Cascade);
public FileEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public FileEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override FileEntityBuilder BuildTable(ColumnsBuilder table) protected override FileEntityBuilder BuildTable(ColumnsBuilder table)
{ {
FileId = table.AddAutoIncrementColumn("FileId"); FileId = ActiveDatabase.AddAutoIncrementColumn(table,"FileId");
FolderId = table.AddIntegerColumn("FolderId"); FolderId = table.AddIntegerColumn("FolderId");
Name = table.AddStringColumn("Name", 50); Name = table.AddStringColumn("Name", 50);
Extension = table.AddStringColumn("Extension", 50); Extension = table.AddStringColumn("Extension", 50);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<FolderEntityBuilder> _primaryKey = new("PK_Folder", x => x.FolderId); private readonly PrimaryKey<FolderEntityBuilder> _primaryKey = new("PK_Folder", x => x.FolderId);
private readonly ForeignKey<FolderEntityBuilder> _siteForeignKey = new("FK_Folder_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade); private readonly ForeignKey<FolderEntityBuilder> _siteForeignKey = new("FK_Folder_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
public FolderEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public FolderEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override FolderEntityBuilder BuildTable(ColumnsBuilder table) protected override FolderEntityBuilder BuildTable(ColumnsBuilder table)
{ {
FolderId = table.AddAutoIncrementColumn("FolderId"); FolderId = ActiveDatabase.AddAutoIncrementColumn(table,"FolderId");
SiteId = table.AddIntegerColumn("SiteId"); SiteId = table.AddIntegerColumn("SiteId");
ParentId = table.AddIntegerColumn("ParentId", true); ParentId = table.AddIntegerColumn("ParentId", true);
Name = table.AddStringColumn("Name", 50); Name = table.AddStringColumn("Name", 50);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "Job"; private const string _entityTableName = "Job";
private readonly PrimaryKey<JobEntityBuilder> _primaryKey = new("PK_Job", x => x.JobId); private readonly PrimaryKey<JobEntityBuilder> _primaryKey = new("PK_Job", x => x.JobId);
public JobEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public JobEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override JobEntityBuilder BuildTable(ColumnsBuilder table) protected override JobEntityBuilder BuildTable(ColumnsBuilder table)
{ {
JobId = table.AddAutoIncrementColumn("JobId"); JobId = ActiveDatabase.AddAutoIncrementColumn(table,"JobId");
Name = table.AddStringColumn("Name", 200); Name = table.AddStringColumn("Name", 200);
JobType = table.AddStringColumn("JobType", 200); JobType = table.AddStringColumn("JobType", 200);
Frequency = table.AddStringColumn("Frequency", 1); Frequency = table.AddStringColumn("Frequency", 1);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global // ReSharper disable UnusedAutoPropertyAccessor.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<JobLogEntityBuilder> _primaryKey = new("PK_JobLog", x => x.JobLogId); private readonly PrimaryKey<JobLogEntityBuilder> _primaryKey = new("PK_JobLog", x => x.JobLogId);
private readonly ForeignKey<JobLogEntityBuilder> _jobLogForeignKey = new("FK_JobLog_Job", x => x.JobId, "Job", "JobId", ReferentialAction.Cascade); private readonly ForeignKey<JobLogEntityBuilder> _jobLogForeignKey = new("FK_JobLog_Job", x => x.JobId, "Job", "JobId", ReferentialAction.Cascade);
public JobLogEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public JobLogEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -22,7 +23,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override JobLogEntityBuilder BuildTable(ColumnsBuilder table) protected override JobLogEntityBuilder BuildTable(ColumnsBuilder table)
{ {
JobLogId = table.AddAutoIncrementColumn("JobLogId"); JobLogId = ActiveDatabase.AddAutoIncrementColumn(table,"JobLogId");
JobId = table.AddIntegerColumn("JobId"); JobId = table.AddIntegerColumn("JobId");
StartDate = table.AddDateTimeColumn("StartDate"); StartDate = table.AddDateTimeColumn("StartDate");
FinishDate = table.AddDateTimeColumn("FinishDate", true); FinishDate = table.AddDateTimeColumn("FinishDate", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<LanguageEntityBuilder> _primaryKey = new("PK_Language", x => x.LanguageId); private readonly PrimaryKey<LanguageEntityBuilder> _primaryKey = new("PK_Language", x => x.LanguageId);
private readonly ForeignKey<LanguageEntityBuilder> _siteForeignKey = new("FK_Language_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade); private readonly ForeignKey<LanguageEntityBuilder> _siteForeignKey = new("FK_Language_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
public LanguageEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public LanguageEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override LanguageEntityBuilder BuildTable(ColumnsBuilder table) protected override LanguageEntityBuilder BuildTable(ColumnsBuilder table)
{ {
LanguageId = table.AddAutoIncrementColumn("LanguageId"); LanguageId = ActiveDatabase.AddAutoIncrementColumn(table,"LanguageId");
SiteId = table.AddIntegerColumn("SiteId"); SiteId = table.AddIntegerColumn("SiteId");
Name = table.AddStringColumn("Name", 100); Name = table.AddStringColumn("Name", 100);
Code = table.AddStringColumn("Code", 10); Code = table.AddStringColumn("Code", 10);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<LogEntityBuilder> _primaryKey = new("PK_Log", x => x.LogId); private readonly PrimaryKey<LogEntityBuilder> _primaryKey = new("PK_Log", x => x.LogId);
private readonly ForeignKey<LogEntityBuilder> _siteForeignKey = new("FK_Log_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade); private readonly ForeignKey<LogEntityBuilder> _siteForeignKey = new("FK_Log_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
public LogEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public LogEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override LogEntityBuilder BuildTable(ColumnsBuilder table) protected override LogEntityBuilder BuildTable(ColumnsBuilder table)
{ {
LogId = table.AddAutoIncrementColumn("LogId"); LogId = ActiveDatabase.AddAutoIncrementColumn(table,"LogId");
SiteId = table.AddIntegerColumn("SiteId", true); SiteId = table.AddIntegerColumn("SiteId", true);
LogDate = table.AddDateTimeColumn("LogDate"); LogDate = table.AddDateTimeColumn("LogDate");
PageId = table.AddIntegerColumn("PageId", true); PageId = table.AddIntegerColumn("PageId", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "ModuleDefinition"; private const string _entityTableName = "ModuleDefinition";
private readonly PrimaryKey<ModuleDefinitionsEntityBuilder> _primaryKey = new("PK_ModuleDefinition", x => x.ModuleDefinitionId); private readonly PrimaryKey<ModuleDefinitionsEntityBuilder> _primaryKey = new("PK_ModuleDefinition", x => x.ModuleDefinitionId);
public ModuleDefinitionsEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public ModuleDefinitionsEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override ModuleDefinitionsEntityBuilder BuildTable(ColumnsBuilder table) protected override ModuleDefinitionsEntityBuilder BuildTable(ColumnsBuilder table)
{ {
ModuleDefinitionId = table.AddAutoIncrementColumn("ModuleDefinitionId"); ModuleDefinitionId = ActiveDatabase.AddAutoIncrementColumn(table,"ModuleDefinitionId");
ModuleDefinitionName = table.AddStringColumn("ModuleDefinitionName", 200); ModuleDefinitionName = table.AddStringColumn("ModuleDefinitionName", 200);
Name = table.AddStringColumn("Name", 200, true); Name = table.AddStringColumn("Name", 200, true);
Description = table.AddStringColumn("Description", 2000, true); Description = table.AddStringColumn("Description", 2000, true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<ModuleEntityBuilder> _primaryKey = new("PK_Module", x => x.ModuleId); private readonly PrimaryKey<ModuleEntityBuilder> _primaryKey = new("PK_Module", x => x.ModuleId);
private readonly ForeignKey<ModuleEntityBuilder> _siteForeignKey = new("FK_Module_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade); private readonly ForeignKey<ModuleEntityBuilder> _siteForeignKey = new("FK_Module_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
public ModuleEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public ModuleEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override ModuleEntityBuilder BuildTable(ColumnsBuilder table) protected override ModuleEntityBuilder BuildTable(ColumnsBuilder table)
{ {
ModuleId = table.AddAutoIncrementColumn("ModuleId"); ModuleId = ActiveDatabase.AddAutoIncrementColumn(table,"ModuleId");
SiteId = table.AddIntegerColumn("SiteId"); SiteId = table.AddIntegerColumn("SiteId");
ModuleDefinitionName = table.AddStringColumn("ModuleDefinitionName", 200); ModuleDefinitionName = table.AddStringColumn("ModuleDefinitionName", 200);
AllPages = table.AddBooleanColumn("AllPages"); AllPages = table.AddBooleanColumn("AllPages");

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<NotificationEntityBuilder> _primaryKey = new("PK_Notification", x => x.NotificationId); private readonly PrimaryKey<NotificationEntityBuilder> _primaryKey = new("PK_Notification", x => x.NotificationId);
private readonly ForeignKey<NotificationEntityBuilder> _siteForeignKey = new("FK_Notification_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade); private readonly ForeignKey<NotificationEntityBuilder> _siteForeignKey = new("FK_Notification_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
public NotificationEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public NotificationEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override NotificationEntityBuilder BuildTable(ColumnsBuilder table) protected override NotificationEntityBuilder BuildTable(ColumnsBuilder table)
{ {
NotificationId = table.AddAutoIncrementColumn("NotificationId"); NotificationId = ActiveDatabase.AddAutoIncrementColumn(table,"NotificationId");
SiteId = table.AddIntegerColumn("SiteId"); SiteId = table.AddIntegerColumn("SiteId");
FromUserId = table.AddIntegerColumn("FromUserId", true); FromUserId = table.AddIntegerColumn("FromUserId", true);
ToUserId = table.AddIntegerColumn("ToUserId", true); ToUserId = table.AddIntegerColumn("ToUserId", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<PageEntityBuilder> _primaryKey = new("PK_Page", x => x.PageId); private readonly PrimaryKey<PageEntityBuilder> _primaryKey = new("PK_Page", x => x.PageId);
private readonly ForeignKey<PageEntityBuilder> _siteForeignKey = new("FK_Page_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade); private readonly ForeignKey<PageEntityBuilder> _siteForeignKey = new("FK_Page_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
public PageEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public PageEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,9 +24,16 @@ namespace Oqtane.Migrations.EntityBuilders
protected override PageEntityBuilder BuildTable(ColumnsBuilder table) protected override PageEntityBuilder BuildTable(ColumnsBuilder table)
{ {
PageId = table.AddAutoIncrementColumn("PageId"); PageId = ActiveDatabase.AddAutoIncrementColumn(table,"PageId");
SiteId = table.AddIntegerColumn("SiteId"); SiteId = table.AddIntegerColumn("SiteId");
Path = table.AddStringColumn("Path", 50); if (ActiveDatabase.Name == "SqlServer" || ActiveDatabase.Name == "LocalDB")
{
Path = table.AddStringColumn("Path", 50);
}
else
{
Path = table.AddStringColumn("Path", 256);
}
Name = table.AddStringColumn("Name", 50); Name = table.AddStringColumn("Name", 50);
Title = table.AddStringColumn("Title", 200, true); Title = table.AddStringColumn("Title", 200, true);
ThemeType = table.AddStringColumn("ThemeType", 200, true); ThemeType = table.AddStringColumn("ThemeType", 200, true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -15,7 +16,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly ForeignKey<PageModuleEntityBuilder> _moduleForeignKey = new("FK_PageModule_Module", x => x.ModuleId, "Module", "ModuleId", ReferentialAction.NoAction); private readonly ForeignKey<PageModuleEntityBuilder> _moduleForeignKey = new("FK_PageModule_Module", x => x.ModuleId, "Module", "ModuleId", ReferentialAction.NoAction);
private readonly ForeignKey<PageModuleEntityBuilder> _pageForeignKey = new("FK_PageModule_Page", x => x.PageId, "Page", "PageId", ReferentialAction.Cascade); private readonly ForeignKey<PageModuleEntityBuilder> _pageForeignKey = new("FK_PageModule_Page", x => x.PageId, "Page", "PageId", ReferentialAction.Cascade);
public PageModuleEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public PageModuleEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -25,7 +26,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override PageModuleEntityBuilder BuildTable(ColumnsBuilder table) protected override PageModuleEntityBuilder BuildTable(ColumnsBuilder table)
{ {
PageModuleId = table.AddAutoIncrementColumn("PageModuleId"); PageModuleId = ActiveDatabase.AddAutoIncrementColumn(table,"PageModuleId");
PageId = table.AddIntegerColumn("PageId"); PageId = table.AddIntegerColumn("PageId");
ModuleId = table.AddIntegerColumn("ModuleId"); ModuleId = table.AddIntegerColumn("ModuleId");
Title = table.AddStringColumn("Title", 200); Title = table.AddStringColumn("Title", 200);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -16,7 +17,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly ForeignKey<PermissionEntityBuilder> _userForeignKey = new("FK_Permission_User", x => x.UserId, "User", "UserId", ReferentialAction.NoAction); private readonly ForeignKey<PermissionEntityBuilder> _userForeignKey = new("FK_Permission_User", x => x.UserId, "User", "UserId", ReferentialAction.NoAction);
private readonly ForeignKey<PermissionEntityBuilder> _roleForeignKey = new("FK_Permission_Role", x => x.RoleId, "Role", "RoleId", ReferentialAction.NoAction); private readonly ForeignKey<PermissionEntityBuilder> _roleForeignKey = new("FK_Permission_Role", x => x.RoleId, "Role", "RoleId", ReferentialAction.NoAction);
public PermissionEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public PermissionEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -27,7 +28,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override PermissionEntityBuilder BuildTable(ColumnsBuilder table) protected override PermissionEntityBuilder BuildTable(ColumnsBuilder table)
{ {
PermissionId = table.AddAutoIncrementColumn("PermissionId"); PermissionId = ActiveDatabase.AddAutoIncrementColumn(table,"PermissionId");
SiteId = table.AddIntegerColumn("SiteId"); SiteId = table.AddIntegerColumn("SiteId");
EntityName = table.AddStringColumn("EntityName", 50); EntityName = table.AddStringColumn("EntityName", 50);
EntityId = table.AddIntegerColumn("EntityId"); EntityId = table.AddIntegerColumn("EntityId");

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<ProfileEntityBuilder> _primaryKey = new("PK_Profile", x => x.ProfileId); private readonly PrimaryKey<ProfileEntityBuilder> _primaryKey = new("PK_Profile", x => x.ProfileId);
private readonly ForeignKey<ProfileEntityBuilder> _siteForeignKey = new("FK_Profile_Sites", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade); private readonly ForeignKey<ProfileEntityBuilder> _siteForeignKey = new("FK_Profile_Sites", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
public ProfileEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public ProfileEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override ProfileEntityBuilder BuildTable(ColumnsBuilder table) protected override ProfileEntityBuilder BuildTable(ColumnsBuilder table)
{ {
ProfileId = table.AddAutoIncrementColumn("ProfileId"); ProfileId = ActiveDatabase.AddAutoIncrementColumn(table,"ProfileId");
SiteId = table.AddIntegerColumn("SiteId", true); SiteId = table.AddIntegerColumn("SiteId", true);
Name = table.AddStringColumn("Name", 50); Name = table.AddStringColumn("Name", 50);
Title = table.AddStringColumn("Title", 50); Title = table.AddStringColumn("Title", 50);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -14,7 +15,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly PrimaryKey<RoleEntityBuilder> _primaryKey = new("PK_Role", x => x.RoleId); private readonly PrimaryKey<RoleEntityBuilder> _primaryKey = new("PK_Role", x => x.RoleId);
private readonly ForeignKey<RoleEntityBuilder> _siteForeignKey = new("FK_Role_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade); private readonly ForeignKey<RoleEntityBuilder> _siteForeignKey = new("FK_Role_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
public RoleEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public RoleEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override RoleEntityBuilder BuildTable(ColumnsBuilder table) protected override RoleEntityBuilder BuildTable(ColumnsBuilder table)
{ {
RoleId = table.AddAutoIncrementColumn("RoleId"); RoleId = ActiveDatabase.AddAutoIncrementColumn(table,"RoleId");
SiteId = table.AddIntegerColumn("SiteId", true); SiteId = table.AddIntegerColumn("SiteId", true);
Name = table.AddStringColumn("Name", 256); Name = table.AddStringColumn("Name", 256);
Description = table.AddStringColumn("Description", 256); Description = table.AddStringColumn("Description", 256);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "Setting"; private const string _entityTableName = "Setting";
private readonly PrimaryKey<SettingEntityBuilder> _primaryKey = new("PK_Setting", x => x.SettingId); private readonly PrimaryKey<SettingEntityBuilder> _primaryKey = new("PK_Setting", x => x.SettingId);
public SettingEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public SettingEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override SettingEntityBuilder BuildTable(ColumnsBuilder table) protected override SettingEntityBuilder BuildTable(ColumnsBuilder table)
{ {
SettingId = table.AddAutoIncrementColumn("SettingId"); SettingId = ActiveDatabase.AddAutoIncrementColumn(table,"SettingId");
EntityName = table.AddStringColumn("EntityName", 50); EntityName = table.AddStringColumn("EntityName", 50);
EntityId = table.AddIntegerColumn("EntityId"); EntityId = table.AddIntegerColumn("EntityId");
SettingName = table.AddStringColumn("SettingName", 50); SettingName = table.AddStringColumn("SettingName", 50);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "Site"; private const string _entityTableName = "Site";
private readonly PrimaryKey<SiteEntityBuilder> _primaryKey = new("PK_Site", x => x.SiteId); private readonly PrimaryKey<SiteEntityBuilder> _primaryKey = new("PK_Site", x => x.SiteId);
public SiteEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public SiteEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override SiteEntityBuilder BuildTable(ColumnsBuilder table) protected override SiteEntityBuilder BuildTable(ColumnsBuilder table)
{ {
SiteId = table.AddAutoIncrementColumn("SiteId"); SiteId = ActiveDatabase.AddAutoIncrementColumn(table,"SiteId");
TenantId = table.AddIntegerColumn("TenantId"); TenantId = table.AddIntegerColumn("TenantId");
Name = table.AddStringColumn("Name", 200); Name = table.AddStringColumn("Name", 200);
LogoFileId = table.AddIntegerColumn("LogoFileId", true); LogoFileId = table.AddIntegerColumn("LogoFileId", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "Tenant"; private const string _entityTableName = "Tenant";
private readonly PrimaryKey<TenantEntityBuilder> _primaryKey = new("PK_Tenant", x => x.TenantId); private readonly PrimaryKey<TenantEntityBuilder> _primaryKey = new("PK_Tenant", x => x.TenantId);
public TenantEntityBuilder(MigrationBuilder migrationBuilder): base(migrationBuilder) public TenantEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database): base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override TenantEntityBuilder BuildTable(ColumnsBuilder table) protected override TenantEntityBuilder BuildTable(ColumnsBuilder table)
{ {
TenantId = table.AddAutoIncrementColumn("TenantId"); TenantId = ActiveDatabase.AddAutoIncrementColumn(table,"TenantId");
Name = table.AddStringColumn("Name", 100); Name = table.AddStringColumn("Name", 100);
DBConnectionString = table.AddStringColumn("DBConnectionString", 1024); DBConnectionString = table.AddStringColumn("DBConnectionString", 1024);
Version = table.AddStringColumn("Version", 50, true); Version = table.AddStringColumn("Version", 50, true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "User"; private const string _entityTableName = "User";
private readonly PrimaryKey<UserEntityBuilder> _primaryKey = new("PK_User", x => x.UserId); private readonly PrimaryKey<UserEntityBuilder> _primaryKey = new("PK_User", x => x.UserId);
public UserEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public UserEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override UserEntityBuilder BuildTable(ColumnsBuilder table) protected override UserEntityBuilder BuildTable(ColumnsBuilder table)
{ {
UserId = table.AddAutoIncrementColumn("UserId"); UserId = ActiveDatabase.AddAutoIncrementColumn(table,"UserId");
Username = table.AddStringColumn("Username", 256); Username = table.AddStringColumn("Username", 256);
DisplayName = table.AddStringColumn("DisplayName", 50); DisplayName = table.AddStringColumn("DisplayName", 50);
Email = table.AddStringColumn("Email", 256); Email = table.AddStringColumn("Email", 256);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -15,7 +16,7 @@ namespace Oqtane.Migrations.EntityBuilders
private readonly ForeignKey<UserRoleEntityBuilder> _userForeignKey = new("FK_UserRole_User", x => x.UserId, "User", "UserId", ReferentialAction.Cascade); private readonly ForeignKey<UserRoleEntityBuilder> _userForeignKey = new("FK_UserRole_User", x => x.UserId, "User", "UserId", ReferentialAction.Cascade);
private readonly ForeignKey<UserRoleEntityBuilder> _roleForeignKey = new("FK_UserRole_Role", x => x.RoleId, "Role", "RoleId", ReferentialAction.NoAction); private readonly ForeignKey<UserRoleEntityBuilder> _roleForeignKey = new("FK_UserRole_Role", x => x.RoleId, "Role", "RoleId", ReferentialAction.NoAction);
public UserRoleEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public UserRoleEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -25,7 +26,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override UserRoleEntityBuilder BuildTable(ColumnsBuilder table) protected override UserRoleEntityBuilder BuildTable(ColumnsBuilder table)
{ {
UserRoleId = table.AddAutoIncrementColumn("UserRoleId"); UserRoleId = ActiveDatabase.AddAutoIncrementColumn(table,"UserRoleId");
UserId = table.AddIntegerColumn("UserId"); UserId = table.AddIntegerColumn("UserId");
RoleId = table.AddIntegerColumn("RoleId"); RoleId = table.AddIntegerColumn("RoleId");
EffectiveDate = table.AddDateTimeColumn("EffectiveDate", true); EffectiveDate = table.AddDateTimeColumn("EffectiveDate", true);

View File

@ -6,14 +6,6 @@ namespace Oqtane.Migrations.Extensions
{ {
public static class ColumnsBuilderExtensions public static class ColumnsBuilderExtensions
{ {
public static OperationBuilder<AddColumnOperation> AddAutoIncrementColumn(this ColumnsBuilder table, string name)
{
return table.Column<int>(name: name, nullable: false)
.Annotation("SqlServer:Identity", "1, 1")
.Annotation("Sqlite:Autoincrement", true)
.Annotation("MySql:ValueGeneratedOnAdd", true);
}
public static OperationBuilder<AddColumnOperation> AddBooleanColumn(this ColumnsBuilder table, string name, bool nullable = false) public static OperationBuilder<AddColumnOperation> AddBooleanColumn(this ColumnsBuilder table, string name, bool nullable = false)
{ {
return table.Column<bool>(name: name, nullable: nullable); return table.Column<bool>(name: name, nullable: nullable);
@ -36,12 +28,12 @@ namespace Oqtane.Migrations.Extensions
public static OperationBuilder<AddColumnOperation> AddMaxStringColumn(this ColumnsBuilder table, string name, bool nullable = false) public static OperationBuilder<AddColumnOperation> AddMaxStringColumn(this ColumnsBuilder table, string name, bool nullable = false)
{ {
return table.Column<string>(name: name, nullable: nullable); return table.Column<string>(name: name, nullable: nullable, unicode: true);
} }
public static OperationBuilder<AddColumnOperation> AddStringColumn(this ColumnsBuilder table, string name, int length, bool nullable = false) public static OperationBuilder<AddColumnOperation> AddStringColumn(this ColumnsBuilder table, string name, int length, bool nullable = false)
{ {
return table.Column<string>(name: name, maxLength: length, nullable: nullable); return table.Column<string>(name: name, maxLength: length, nullable: nullable, unicode: true);
} }
} }

View File

@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
namespace Oqtane.Migrations
{
public abstract class MultiDatabaseMigration : Migration
{
private readonly IEnumerable<IOqtaneDatabase> _databases;
protected MultiDatabaseMigration(IEnumerable<IOqtaneDatabase> databases)
{
_databases = databases;
}
protected IOqtaneDatabase ActiveDatabase => _databases.FirstOrDefault(d => d.Provider == ActiveProvider);
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Internal;
using Oqtane.Interfaces;
using Oqtane.Repository.Databases.Interfaces;
namespace Oqtane.Migrations.Framework
{
public class MultiDatabaseMigrationsAssembly: MigrationsAssembly
{
private readonly IEnumerable<IOqtaneDatabase> _databases;
public MultiDatabaseMigrationsAssembly(
ICurrentDbContext currentContext,
IDbContextOptions options,
IMigrationsIdGenerator idGenerator,
IDiagnosticsLogger<DbLoggerCategory.Migrations> logger)
: base(currentContext, options, idGenerator, logger)
{
var multiDatabaseContext = currentContext.Context as IMultiDatabase;
if (multiDatabaseContext != null) _databases = multiDatabaseContext.Databases;
}
public override Migration CreateMigration(TypeInfo migrationClass, string activeProvider)
{
var hasCtorWithCacheOptions = migrationClass.GetConstructor(new[] { typeof(IEnumerable<IOqtaneDatabase>) }) != null;
if (hasCtorWithCacheOptions)
{
var migration = (Migration)Activator.CreateInstance(migrationClass.AsType(), _databases);
if (migration != null)
{
migration.ActiveProvider = activeProvider;
return migration;
}
}
return base.CreateMigration(migrationClass, activeProvider);
}
}
}

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using Oqtane.Infrastructure; using Oqtane.Infrastructure;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Repository; using Oqtane.Repository;
@ -8,6 +9,8 @@ using System.Net;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Enums; using Oqtane.Enums;
using Oqtane.Interfaces;
// ReSharper disable ConvertToUsingDeclaration // ReSharper disable ConvertToUsingDeclaration
namespace Oqtane.Modules.HtmlText.Manager namespace Oqtane.Modules.HtmlText.Manager
@ -15,12 +18,12 @@ namespace Oqtane.Modules.HtmlText.Manager
public class HtmlTextManager : MigratableModuleBase, IInstallable, IPortable public class HtmlTextManager : MigratableModuleBase, IInstallable, IPortable
{ {
private readonly IHtmlTextRepository _htmlText; private readonly IHtmlTextRepository _htmlText;
private readonly ISqlRepository _sql; private readonly IEnumerable<IOqtaneDatabase> _databases;
public HtmlTextManager(IHtmlTextRepository htmlText, ISqlRepository sql) public HtmlTextManager(IHtmlTextRepository htmlText, IEnumerable<IOqtaneDatabase> databases)
{ {
_htmlText = htmlText; _htmlText = htmlText;
_sql = sql; _databases = databases;
} }
public string ExportModule(Module module) public string ExportModule(Module module)
@ -54,13 +57,13 @@ namespace Oqtane.Modules.HtmlText.Manager
public bool Install(Tenant tenant, string version) public bool Install(Tenant tenant, string version)
{ {
var dbConfig = new DbConfig(null, null) {ConnectionString = tenant.DBConnectionString, DatabaseType = tenant.DBType}; var dbConfig = new DbConfig(null, null, _databases) {ConnectionString = tenant.DBConnectionString, DatabaseType = tenant.DBType};
return Migrate(new HtmlTextContext(dbConfig, null), tenant, MigrationType.Up); return Migrate(new HtmlTextContext(dbConfig, null), tenant, MigrationType.Up);
} }
public bool Uninstall(Tenant tenant) public bool Uninstall(Tenant tenant)
{ {
var dbConfig = new DbConfig(null, null) {ConnectionString = tenant.DBConnectionString, DatabaseType = tenant.DBType}; var dbConfig = new DbConfig(null, null, _databases) {ConnectionString = tenant.DBConnectionString, DatabaseType = tenant.DBType};
return Migrate(new HtmlTextContext(dbConfig, null), tenant, MigrationType.Down); return Migrate(new HtmlTextContext(dbConfig, null), tenant, MigrationType.Down);
} }
} }

View File

@ -1,5 +1,8 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations;
using Oqtane.Modules.HtmlText.Migrations.EntityBuilders; using Oqtane.Modules.HtmlText.Migrations.EntityBuilders;
using Oqtane.Modules.HtmlText.Repository; using Oqtane.Modules.HtmlText.Repository;
@ -7,19 +10,23 @@ namespace Oqtane.Modules.HtmlText.Migrations
{ {
[DbContext(typeof(HtmlTextContext))] [DbContext(typeof(HtmlTextContext))]
[Migration("HtmlText.01.00.00.00")] [Migration("HtmlText.01.00.00.00")]
public class InitializeModule : Migration public class InitializeModule : MultiDatabaseMigration
{ {
public InitializeModule(IEnumerable<IOqtaneDatabase> databases) : base(databases)
{
}
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Create HtmlText table //Create HtmlText table
var entityBuilder = new HtmlTextEntityBuilder(migrationBuilder); var entityBuilder = new HtmlTextEntityBuilder(migrationBuilder, ActiveDatabase);
entityBuilder.Create(); entityBuilder.Create();
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
//Drop HtmlText table //Drop HtmlText table
var entityBuilder = new HtmlTextEntityBuilder(migrationBuilder); var entityBuilder = new HtmlTextEntityBuilder(migrationBuilder, ActiveDatabase);
entityBuilder.Drop(); entityBuilder.Drop();
} }
} }

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations; using Oqtane.Migrations;
using Oqtane.Migrations.EntityBuilders; using Oqtane.Migrations.EntityBuilders;
using Oqtane.Migrations.Extensions; using Oqtane.Migrations.Extensions;
@ -16,7 +17,7 @@ namespace Oqtane.Modules.HtmlText.Migrations.EntityBuilders
private readonly PrimaryKey<HtmlTextEntityBuilder> _primaryKey = new("PK_HtmlText", x => x.HtmlTextId); private readonly PrimaryKey<HtmlTextEntityBuilder> _primaryKey = new("PK_HtmlText", x => x.HtmlTextId);
private readonly ForeignKey<HtmlTextEntityBuilder> _moduleForeignKey = new("FK_HtmlText_Module", x => x.ModuleId, "Module", "ModuleId", ReferentialAction.Cascade); private readonly ForeignKey<HtmlTextEntityBuilder> _moduleForeignKey = new("FK_HtmlText_Module", x => x.ModuleId, "Module", "ModuleId", ReferentialAction.Cascade);
public HtmlTextEntityBuilder(MigrationBuilder migrationBuilder) : base(migrationBuilder) public HtmlTextEntityBuilder(MigrationBuilder migrationBuilder, IOqtaneDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
@ -25,7 +26,7 @@ namespace Oqtane.Modules.HtmlText.Migrations.EntityBuilders
protected override HtmlTextEntityBuilder BuildTable(ColumnsBuilder table) protected override HtmlTextEntityBuilder BuildTable(ColumnsBuilder table)
{ {
HtmlTextId = table.AddAutoIncrementColumn("HtmlTextId"); HtmlTextId = ActiveDatabase.AddAutoIncrementColumn(table,"HtmlTextId");
ModuleId = table.AddIntegerColumn("ModuleId"); ModuleId = table.AddIntegerColumn("ModuleId");
Content = table.AddMaxStringColumn("Content"); Content = table.AddMaxStringColumn("Content");

View File

@ -1,18 +1,21 @@
using Microsoft.EntityFrameworkCore; using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Oqtane.Modules.HtmlText.Models; using Oqtane.Modules.HtmlText.Models;
using Oqtane.Repository; using Oqtane.Repository;
using Microsoft.AspNetCore.Http; using Oqtane.Interfaces;
using Microsoft.Extensions.Configuration; using Oqtane.Repository.Databases.Interfaces;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace Oqtane.Modules.HtmlText.Repository namespace Oqtane.Modules.HtmlText.Repository
{ {
public class HtmlTextContext : DBContextBase, IService public class HtmlTextContext : DBContextBase, IService, IMultiDatabase
{ {
public virtual DbSet<HtmlTextInfo> HtmlText { get; set; }
public HtmlTextContext(IDbConfig dbConfig, ITenantResolver tenantResolver) : base(dbConfig, tenantResolver) public HtmlTextContext(IDbConfig dbConfig, ITenantResolver tenantResolver) : base(dbConfig, tenantResolver)
{ {
// ContextBase handles multi-tenant database connections
} }
public virtual DbSet<HtmlTextInfo> HtmlText { get; set; }
} }
} }

View File

@ -50,7 +50,6 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.4" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.4" /> <PackageReference Include="Microsoft.Extensions.Localization" Version="5.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
@ -58,6 +57,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Oqtane.Client\Oqtane.Client.csproj" /> <ProjectReference Include="..\Oqtane.Client\Oqtane.Client.csproj" />
<ProjectReference Include="..\Oqtane.Database.MySQL\Oqtane.Database.MySQL.csproj" />
<ProjectReference Include="..\Oqtane.Database.PostgreSQL\Oqtane.Database.PostgreSQL.csproj" />
<ProjectReference Include="..\Oqtane.Database.Sqlite\Oqtane.Database.Sqlite.csproj" />
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" /> <ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
<ProjectReference Include="..\Oqtane.Upgrade\Oqtane.Upgrade.csproj" /> <ProjectReference Include="..\Oqtane.Upgrade\Oqtane.Upgrade.csproj" />
</ItemGroup> </ItemGroup>

View File

@ -1,10 +1,16 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Oqtane.Extensions; using Oqtane.Extensions;
using Oqtane.Interfaces;
using Oqtane.Migrations.Framework;
using Oqtane.Repository.Databases.Interfaces;
using Oqtane.Shared; using Oqtane.Shared;
// ReSharper disable BuiltInTypeReferenceStyleForMemberAccess // ReSharper disable BuiltInTypeReferenceStyleForMemberAccess
@ -32,11 +38,16 @@ namespace Oqtane.Repository
_configuration = dbConfig.Configuration; _configuration = dbConfig.Configuration;
_connectionString = dbConfig.ConnectionString; _connectionString = dbConfig.ConnectionString;
_databaseType = dbConfig.DatabaseType; _databaseType = dbConfig.DatabaseType;
Databases = dbConfig.Databases;
_tenantResolver = tenantResolver; _tenantResolver = tenantResolver;
} }
public IEnumerable<IOqtaneDatabase> Databases { get; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ {
optionsBuilder.ReplaceService<IMigrationsAssembly, MultiDatabaseMigrationsAssembly>();
if (string.IsNullOrEmpty(_connectionString) && _tenantResolver != null) if (string.IsNullOrEmpty(_connectionString) && _tenantResolver != null)
{ {
var tenant = _tenantResolver.GetTenant(); var tenant = _tenantResolver.GetTenant();
@ -60,7 +71,14 @@ namespace Oqtane.Repository
if (!string.IsNullOrEmpty(_connectionString) && !string.IsNullOrEmpty(_databaseType)) if (!string.IsNullOrEmpty(_connectionString) && !string.IsNullOrEmpty(_databaseType))
{ {
optionsBuilder.UseOqtaneDatabase(_databaseType, _connectionString); if (Databases != null)
{
optionsBuilder.UseOqtaneDatabase(Databases.Single(d => d.Name == _databaseType), _connectionString);
}
else
{
optionsBuilder.UseOqtaneDatabase(_databaseType, _connectionString);
}
} }
base.OnConfiguring(optionsBuilder); base.OnConfiguring(optionsBuilder);

View File

@ -1,20 +1,25 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Oqtane.Interfaces;
namespace Oqtane.Repository namespace Oqtane.Repository
{ {
public class DbConfig : IDbConfig public class DbConfig : IDbConfig
{ {
public DbConfig(IHttpContextAccessor accessor, IConfiguration configuration) public DbConfig(IHttpContextAccessor accessor, IConfiguration configuration, IEnumerable<IOqtaneDatabase> databases)
{ {
Accessor = accessor; Accessor = accessor;
Configuration = configuration; Configuration = configuration;
Databases = databases;
} }
public IHttpContextAccessor Accessor { get; } public IHttpContextAccessor Accessor { get; }
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }
public IEnumerable<IOqtaneDatabase> Databases { get; set; }
public string ConnectionString { get; set; } public string ConnectionString { get; set; }
public string DatabaseType { get; set; } public string DatabaseType { get; set; }

View File

@ -1,24 +1,29 @@
using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage;
using Oqtane.Extensions; using Oqtane.Extensions;
using Oqtane.Interfaces;
using Oqtane.Models; using Oqtane.Models;
// ReSharper disable CheckNamespace
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace Oqtane.Repository namespace Oqtane.Repository
{ {
public class InstallationContext : DbContext public class InstallationContext : DbContext
{ {
private readonly string _connectionString; private readonly string _connectionString;
private readonly string _databaseType; private readonly IOqtaneDatabase _database;
public InstallationContext(string databaseType, string connectionString) public InstallationContext(IOqtaneDatabase database, string connectionString)
{ {
_connectionString = connectionString; _connectionString = connectionString;
_databaseType = databaseType; _database = database;
} }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseOqtaneDatabase(_databaseType, _connectionString); => optionsBuilder.UseOqtaneDatabase(_database, _connectionString);
public virtual DbSet<Alias> Alias { get; set; } public virtual DbSet<Alias> Alias { get; set; }
public virtual DbSet<Tenant> Tenant { get; set; } public virtual DbSet<Tenant> Tenant { get; set; }

View File

@ -1,9 +1,14 @@
using System; using System;
using Microsoft.AspNetCore.Http; using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Models; using Oqtane.Models;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Oqtane.Extensions; using Oqtane.Extensions;
using Oqtane.Interfaces;
using Oqtane.Migrations.Framework;
using Oqtane.Repository.Databases.Interfaces;
using Oqtane.Shared; using Oqtane.Shared;
// ReSharper disable BuiltInTypeReferenceStyleForMemberAccess // ReSharper disable BuiltInTypeReferenceStyleForMemberAccess
@ -12,17 +17,22 @@ using Oqtane.Shared;
namespace Oqtane.Repository namespace Oqtane.Repository
{ {
public class MasterDBContext : DbContext public class MasterDBContext : DbContext, IMultiDatabase
{ {
private readonly IDbConfig _dbConfig; private readonly IDbConfig _dbConfig;
public MasterDBContext(DbContextOptions<MasterDBContext> options, IDbConfig dbConfig) : base(options) public MasterDBContext(DbContextOptions<MasterDBContext> options, IDbConfig dbConfig) : base(options)
{ {
_dbConfig = dbConfig; _dbConfig = dbConfig;
Databases = dbConfig.Databases;
} }
public IEnumerable<IOqtaneDatabase> Databases { get; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ {
optionsBuilder.ReplaceService<IMigrationsAssembly, MultiDatabaseMigrationsAssembly>();
var connectionString = _dbConfig.ConnectionString; var connectionString = _dbConfig.ConnectionString;
var configuration = _dbConfig.Configuration; var configuration = _dbConfig.Configuration;
var databaseType = _dbConfig.DatabaseType; var databaseType = _dbConfig.DatabaseType;
@ -38,10 +48,18 @@ namespace Oqtane.Repository
databaseType = configuration.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey]; databaseType = configuration.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey];
} }
if (!string.IsNullOrEmpty(connectionString)) if (!string.IsNullOrEmpty(connectionString) && !string.IsNullOrEmpty(databaseType))
{ {
optionsBuilder.UseOqtaneDatabase(databaseType, connectionString); if (Databases != null)
{
optionsBuilder.UseOqtaneDatabase(Databases.Single(d => d.Name == databaseType), connectionString);
}
else
{
optionsBuilder.UseOqtaneDatabase(databaseType, connectionString);
}
} }
base.OnConfiguring(optionsBuilder); base.OnConfiguring(optionsBuilder);
} }

View File

@ -1,12 +1,19 @@
using Microsoft.AspNetCore.Http; using System.Collections.Generic;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Oqtane.Interfaces;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Repository.Databases.Interfaces;
// ReSharper disable CheckNamespace
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace Oqtane.Repository namespace Oqtane.Repository
{ {
public class TenantDBContext : DBContextBase public class TenantDBContext : DBContextBase, IMultiDatabase
{ {
public TenantDBContext(IDbConfig dbConfig, ITenantResolver tenantResolver) : base(dbConfig, tenantResolver) { }
public virtual DbSet<Site> Site { get; set; } public virtual DbSet<Site> Site { get; set; }
public virtual DbSet<Page> Page { get; set; } public virtual DbSet<Page> Page { get; set; }
public virtual DbSet<PageModule> PageModule { get; set; } public virtual DbSet<PageModule> PageModule { get; set; }
@ -21,13 +28,6 @@ namespace Oqtane.Repository
public virtual DbSet<Notification> Notification { get; set; } public virtual DbSet<Notification> Notification { get; set; }
public virtual DbSet<Folder> Folder { get; set; } public virtual DbSet<Folder> Folder { get; set; }
public virtual DbSet<File> File { get; set; } public virtual DbSet<File> File { get; set; }
public virtual DbSet<Language> Language { get; set; } public virtual DbSet<Language> Language { get; set; }
public TenantDBContext(IDbConfig dbConfig, ITenantResolver tenantResolver) : base(dbConfig, tenantResolver)
{
// DBContextBase handles multi-tenant database connections
}
} }
} }

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Oqtane.Interfaces;
namespace Oqtane.Repository namespace Oqtane.Repository
{ {
@ -9,7 +11,10 @@ namespace Oqtane.Repository
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }
public IEnumerable<IOqtaneDatabase> Databases { get; set; }
public string ConnectionString { get; set; } public string ConnectionString { get; set; }
public string DatabaseType { get; set; } public string DatabaseType { get; set; }
} }
} }

View File

@ -130,10 +130,6 @@ namespace Oqtane
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IDbConfig, DbConfig>();
services.AddDbContext<MasterDBContext>(options => { });
services.AddDbContext<TenantDBContext>(options => { });
services.AddIdentityCore<IdentityUser>(options => { }) services.AddIdentityCore<IdentityUser>(options => { })
.AddEntityFrameworkStores<TenantDBContext>() .AddEntityFrameworkStores<TenantDBContext>()
.AddSignInManager() .AddSignInManager()
@ -214,6 +210,10 @@ namespace Oqtane
// load the external assemblies into the app domain, install services // load the external assemblies into the app domain, install services
services.AddOqtane(_runtime, _supportedCultures); services.AddOqtane(_runtime, _supportedCultures);
services.AddScoped<IDbConfig, DbConfig>();
services.AddDbContext<MasterDBContext>(options => { });
services.AddDbContext<TenantDBContext>(options => { });
services.AddMvc() services.AddMvc()
.AddNewtonsoftJson() .AddNewtonsoftJson()

View File

@ -1,13 +0,0 @@
using Microsoft.EntityFrameworkCore;
namespace Oqtane.Interfaces
{
public interface IDatabase
{
public string FriendlyName { get; }
public string Name { get; }
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString);
}
}

View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Models;
namespace Oqtane.Interfaces
{
public interface IOqtaneDatabase
{
public string FriendlyName { get; }
public string Name { get; }
public string Provider { get; }
public List<ConnectionStringField> ConnectionStringFields { get; }
public OperationBuilder<AddColumnOperation> AddAutoIncrementColumn(ColumnsBuilder table, string name);
public string BuildConnectionString();
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString);
}
}

View File

@ -0,0 +1,11 @@
namespace Oqtane.Models
{
public class ConnectionStringField
{
public string FriendlyName { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
}

View File

@ -19,9 +19,16 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="5.0.1" /> <PackageReference Include="System.Text.Json" Version="5.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.EntityFrameworkCore.Relational, Version=5.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
<HintPath>C:\Users\charl\.nuget\packages\microsoft.entityframeworkcore.relational\5.0.2\lib\netstandard2.1\Microsoft.EntityFrameworkCore.Relational.dll</HintPath>
</Reference>
</ItemGroup>
</Project> </Project>

View File

@ -20,6 +20,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md README.md = README.md
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Oqtane.Database.MySQL", "Oqtane.Database.MySQL\Oqtane.Database.MySQL.csproj", "{A996FD2D-DAC8-4DFA-92B2-51DF32C6E014}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Oqtane.Database.PostgreSQL", "Oqtane.Database.PostgreSQL\Oqtane.Database.PostgreSQL.csproj", "{3B29B35F-65E7-4819-9AED-EAC7FCFA309B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Oqtane.Database.Sqlite", "Oqtane.Database.Sqlite\Oqtane.Database.Sqlite.csproj", "{E4F50CA9-19A6-465A-9469-C033748AD95B}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -46,6 +52,18 @@ Global
{823B556D-8D4E-4BB8-A65A-C4EB5E7E7424}.Debug|Any CPU.Build.0 = Debug|Any CPU {823B556D-8D4E-4BB8-A65A-C4EB5E7E7424}.Debug|Any CPU.Build.0 = Debug|Any CPU
{823B556D-8D4E-4BB8-A65A-C4EB5E7E7424}.Release|Any CPU.ActiveCfg = Release|Any CPU {823B556D-8D4E-4BB8-A65A-C4EB5E7E7424}.Release|Any CPU.ActiveCfg = Release|Any CPU
{823B556D-8D4E-4BB8-A65A-C4EB5E7E7424}.Release|Any CPU.Build.0 = Release|Any CPU {823B556D-8D4E-4BB8-A65A-C4EB5E7E7424}.Release|Any CPU.Build.0 = Release|Any CPU
{A996FD2D-DAC8-4DFA-92B2-51DF32C6E014}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A996FD2D-DAC8-4DFA-92B2-51DF32C6E014}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A996FD2D-DAC8-4DFA-92B2-51DF32C6E014}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A996FD2D-DAC8-4DFA-92B2-51DF32C6E014}.Release|Any CPU.Build.0 = Release|Any CPU
{3B29B35F-65E7-4819-9AED-EAC7FCFA309B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B29B35F-65E7-4819-9AED-EAC7FCFA309B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B29B35F-65E7-4819-9AED-EAC7FCFA309B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B29B35F-65E7-4819-9AED-EAC7FCFA309B}.Release|Any CPU.Build.0 = Release|Any CPU
{E4F50CA9-19A6-465A-9469-C033748AD95B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E4F50CA9-19A6-465A-9469-C033748AD95B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E4F50CA9-19A6-465A-9469-C033748AD95B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4F50CA9-19A6-465A-9469-C033748AD95B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE