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
var databaseTypes = assembly.GetInterfaces<IDatabase>();
var databaseTypes = assembly.GetInterfaces<IOqtaneDatabase>();
foreach (var databaseType in databaseTypes)
{
if (databaseType.AssemblyQualifiedName != null)

View File

@ -1,4 +1,5 @@
@using Oqtane.Interfaces
@using System.Reflection
@namespace Oqtane.UI
@inject NavigationManager NavigationManager
@inject IInstallationService InstallationService
@ -6,7 +7,7 @@
@inject IUserService UserService
@inject IJSRuntime JSRuntime
@inject IStringLocalizer<Installer> Localizer
@inject IEnumerable<IDatabase> Databases
@inject IEnumerable<IOqtaneDatabase> Databases
<div class="container">
<div class="row">
@ -36,57 +37,50 @@
</select>
</td>
</tr>
<tr style="@(_databaseType == "Sqlite" ? "" : "display: none")">
<td>
<label class="control-label" style="font-weight: bold">@Localizer["File Name:"] </label>
</td>
<td>
<input type="text" class="form-control" @bind="@_fileName" />
</td>
</tr>
<tr style="@(_databaseType == "Sqlite" ? "display: none" : "")">
<td>
<label class="control-label" style="font-weight: bold">@Localizer["Server:"] </label>
</td>
<td>
<input type="text" class="form-control" @bind="@_serverName" />
</td>
</tr>
<tr style="@(_databaseType == "Sqlite" ? "display: none" : "")">
<td>
<label class="control-label" style="font-weight: bold">@Localizer["Database:"] </label>
</td>
<td>
<input type="text" class="form-control" @bind="@_databaseName" />
</td>
</tr>
<tr style="@(_databaseType == "Sqlite" ? "display: none" : "")">
<td>
<label class="control-label" style="font-weight: bold">@Localizer["Integrated Security:"] </label>
</td>
<td>
<select class="custom-select" @onchange="SetIntegratedSecurity">
<option value="true" selected>@Localizer["True"]</option>
<option value="false">@Localizer["False"]</option>
</select>
</td>
</tr>
<tr style="@_integratedSecurityDisplay">
<td>
<label class="control-label" style="font-weight: bold">@Localizer["Username:"] </label>
</td>
<td>
<input type="text" class="form-control" @bind="@_username" />
</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>
@{
_selectedDatabase = Databases.Single(d => d.Name == _databaseType);
foreach (var field in _selectedDatabase.ConnectionStringFields)
{
if (field.Name != "IntegratedSecurity")
{
var isVisible = "";
var fieldType = (field.Name == "Pwd") ? "password" : "text";
if ((field.Name == "Uid" || field.Name == "Pwd") && _selectedDatabase.Name != "MySQL" )
{
var intSecurityField = _selectedDatabase.ConnectionStringFields.Single(f => f.Name == "IntegratedSecurity");
if (intSecurityField != null)
{
isVisible = (Convert.ToBoolean(intSecurityField.Value)) ? "display: none;" : "";
}
}
field.Value = field.Value.Replace("{{Date}}", DateTime.UtcNow.ToString("yyyyMMddHHmm"));
<tr style="@isVisible">
<td>
<label class="control-label" style="font-weight: bold">@Localizer[$"{field.FriendlyName}:"]</label>
</td>
<td>
<input type="@fieldType" class="form-control" @bind="@field.Value" />
</td>
</tr>
}
else
{
<tr>
<td>
<label class="control-label" style="font-weight: bold">@Localizer[$"{field.FriendlyName}:"]</label>
</td>
<td>
<select class="custom-select" @bind="@field.Value">
<option value="true" selected>@Localizer["True"]</option>
<option value="false">@Localizer["False"]</option>
</select>
</td>
</tr>
}
}
}
</tbody>
</table>
</div>
@ -141,18 +135,13 @@
</div>
@code {
private IOqtaneDatabase _selectedDatabase;
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 _hostPassword = string.Empty;
private string _confirmPassword = string.Empty;
private string _hostEmail = string.Empty;
private string _message = string.Empty;
private string _integratedSecurityDisplay = "display: none;";
private string _loadingDisplay = "display: none;";
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()
{
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 = "";
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);
var config = new InstallConfig
{
DatabaseType = fullyQualifiedType,
ConnectionString = connectionstring,
DatabaseType = _databaseType,
ConnectionString = connectionString,
Aliases = uri.Authority,
HostEmail = _hostEmail,
HostPassword = _hostPassword,
@ -219,8 +177,6 @@
SiteName = Constants.DefaultSite
};
var installation = await InstallationService.Install(config);
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 Oqtane.Interfaces;
using System;
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";
public string Name => "LocalDB";
private static string _friendlyName => "Local Database";
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 Oqtane.Interfaces;
using System;
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";
public DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString)
private static readonly List<ConnectionStringField> _connectionStringFields = new()
{
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.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Oqtane.Interfaces;
// ReSharper disable ConvertToUsingDeclaration
@ -10,14 +8,22 @@ namespace Oqtane.Extensions
{
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)
{
var type = Type.GetType(databaseType);
var database = Activator.CreateInstance(type) as IDatabase;
var database = Activator.CreateInstance(type) as IOqtaneDatabase;
database.UseDatabase(optionsBuilder, connectionString);
return optionsBuilder;
}
}
}

View File

@ -48,12 +48,12 @@ namespace Microsoft.Extensions.DependencyInjection
}
// dynamically register database providers
var databaseTypes = assembly.GetInterfaces<IDatabase>();
var databaseTypes = assembly.GetInterfaces<IOqtaneDatabase>();
foreach (var databaseType in databaseTypes)
{
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);
}
}

View File

@ -13,6 +13,7 @@ using Oqtane.Models;
using Oqtane.Repository;
using Oqtane.Shared;
using Oqtane.Enums;
using Oqtane.Interfaces;
using File = System.IO.File;
// ReSharper disable MemberCanBePrivate.Global
@ -172,11 +173,16 @@ namespace Oqtane.Infrastructure
var connectionString = NormalizeConnectionString(install.ConnectionString);
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
dbc.Database.EnsureCreated();
result.Success = true;
var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
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)
@ -198,26 +204,31 @@ namespace Oqtane.Infrastructure
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
masterDbContext.Database.Migrate();
result.Success = true;
}
}
catch (Exception ex)
{
result.Message = ex.Message;
}
var dbConfig = new DbConfig(null, null, databases) {ConnectionString = install.ConnectionString, DatabaseType = install.DatabaseType};
if (result.Success)
{
UpdateConnectionString(install.ConnectionString);
UpdateDatabaseType(install.DatabaseType);
using (var masterDbContext = new MasterDBContext(new DbContextOptions<MasterDBContext>(), dbConfig))
{
// Push latest model into database
masterDbContext.Database.Migrate();
result.Success = true;
}
}
catch (Exception ex)
{
result.Message = ex.Message;
}
if (result.Success)
{
UpdateConnectionString(install.ConnectionString);
UpdateDatabaseType(install.DatabaseType);
}
}
}
else
@ -234,38 +245,56 @@ namespace Oqtane.Infrastructure
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases))
{
using (var db = GetInstallationContext())
using (var scope = _serviceScopeFactory.CreateScope())
{
Tenant tenant;
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);
}
var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
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 };
db.Alias.Add(alias);
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);
}
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;
}
private InstallationContext GetInstallationContext()
private InstallationContext GetInstallationContext(IEnumerable<IOqtaneDatabase> databases)
{
var databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey];
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)
@ -291,14 +320,15 @@ namespace Oqtane.Infrastructure
using (var scope = _serviceScopeFactory.CreateScope())
{
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())
{
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))
{
// Push latest model into database
@ -345,6 +375,8 @@ namespace Oqtane.Infrastructure
{
var moduleDefinitions = scope.ServiceProvider.GetRequiredService<IModuleDefinitionRepository>();
var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>();
var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
foreach (var moduleDefinition in moduleDefinitions.GetModuleDefinitions())
{
if (!string.IsNullOrEmpty(moduleDefinition.ReleaseVersions) && !string.IsNullOrEmpty(moduleDefinition.ServerManagerType))
@ -353,7 +385,7 @@ namespace Oqtane.Infrastructure
if (moduleType != null)
{
var versions = moduleDefinition.ReleaseVersions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
using (var db = GetInstallationContext())
using (var db = GetInstallationContext(databases))
{
foreach (var tenant in db.Tenant.ToList())
{

View File

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Migrations.Extensions;
using Oqtane.Repository;
@ -9,52 +11,57 @@ namespace Oqtane.Migrations
{
[DbContext(typeof(MasterDBContext))]
[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)
{
//Create Tenant table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.Create();
//Create Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.Create();
//Create ModuleDefinitions Table
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder);
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder, ActiveDatabase);
moduleDefinitionsEntityBuilder.Create();
//Create Job Table
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder);
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder, ActiveDatabase);
jobEntityBuilder.Create();
//Create JobLog Table
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder);
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder, ActiveDatabase);
jobLogEntityBuilder.Create();
}
protected override void Down(MigrationBuilder migrationBuilder)
{
//Drop Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.Drop();
//Drop JobLog Table
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder);
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder, ActiveDatabase);
jobLogEntityBuilder.Drop();
//Drop Tenant table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.Drop();
//Drop ModuleDefinitions Table
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder);
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder, ActiveDatabase);
moduleDefinitionsEntityBuilder.Drop();
//Drop Job Table
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder);
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder, ActiveDatabase);
jobEntityBuilder.Drop();
}
}
}

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
@ -8,86 +10,90 @@ namespace Oqtane.Migrations
{
[DbContext(typeof(TenantDBContext))]
[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)
{
//Create Site table
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder);
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
siteEntityBuilder.Create();
//Create Page table
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
pageEntityBuilder.Create();
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
if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.SqlServer")
if (ActiveDatabase.Name == "SqlServer" || ActiveDatabase.Name == "LocalDB")
{
pageEntityBuilder.AddBooleanColumn("EditMode");
}
//Create Module table
var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder);
var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder, ActiveDatabase);
moduleEntityBuilder.Create();
//Create PageModule table
var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder);
var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder, ActiveDatabase);
pageModuleEntityBuilder.Create();
//Create User table
var userEntityBuilder = new UserEntityBuilder(migrationBuilder);
var userEntityBuilder = new UserEntityBuilder(migrationBuilder, ActiveDatabase);
userEntityBuilder.Create();
userEntityBuilder.AddIndex("IX_User", "Username", true);
//Create Role table
var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder);
var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder, ActiveDatabase);
roleEntityBuilder.Create();
//Create UserRole table
var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder);
var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder, ActiveDatabase);
userRoleEntityBuilder.Create();
userRoleEntityBuilder.AddIndex("IX_UserRole", new [] {"RoleId", "UserId"}, true);
//Create Permission table
var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder);
var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder, ActiveDatabase);
permissionEntityBuilder.Create();
permissionEntityBuilder.AddIndex("IX_Permission", new [] {"SiteId", "EntityName", "EntityId", "PermissionName", "RoleId", "UserId"}, true);
//Create Setting table
var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder);
var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder, ActiveDatabase);
settingEntityBuilder.Create();
settingEntityBuilder.AddIndex("IX_Setting", new [] {"EntityName", "EntityId", "SettingName"}, true);
//Create Profile table
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder);
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
profileEntityBuilder.Create();
//Create Log table
var logEntityBuilder = new LogEntityBuilder(migrationBuilder);
var logEntityBuilder = new LogEntityBuilder(migrationBuilder, ActiveDatabase);
logEntityBuilder.Create();
//Create Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.Create();
//Create Folder table
var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder);
var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder, ActiveDatabase);
folderEntityBuilder.Create();
folderEntityBuilder.AddIndex("IX_Folder", new [] {"SiteId", "Path"}, true);
//Create File table
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder);
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder, ActiveDatabase);
fileEntityBuilder.Create();
//Create AspNetUsers table
var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder);
var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder, ActiveDatabase);
aspNetUsersEntityBuilder.Create();
aspNetUsersEntityBuilder.AddIndex("EmailIndex", "NormalizedEmail", true);
aspNetUsersEntityBuilder.AddIndex("UserNameIndex", "NormalizedUserName", true);
//Create AspNetUserClaims table
var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder);
var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder, ActiveDatabase);
aspNetUserClaimsEntityBuilder.Create();
aspNetUserClaimsEntityBuilder.AddIndex("IX_AspNetUserClaims_UserId", "UserId", true);
@ -96,67 +102,67 @@ namespace Oqtane.Migrations
protected override void Down(MigrationBuilder migrationBuilder)
{
//Drop AspNetUserClaims table
var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder);
var aspNetUserClaimsEntityBuilder = new AspNetUserClaimsEntityBuilder(migrationBuilder, ActiveDatabase);
aspNetUserClaimsEntityBuilder.Drop();
//Drop AspNetUsers table
var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder);
var aspNetUsersEntityBuilder = new AspNetUsersEntityBuilder(migrationBuilder, ActiveDatabase);
aspNetUsersEntityBuilder.Drop();
//Drop File table
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder);
var fileEntityBuilder = new FileEntityBuilder(migrationBuilder, ActiveDatabase);
fileEntityBuilder.Drop();
//Drop Folder table
var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder);
var folderEntityBuilder = new FolderEntityBuilder(migrationBuilder, ActiveDatabase);
folderEntityBuilder.Drop();
//Drop Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.Drop();
//Drop Log table
var logEntityBuilder = new LogEntityBuilder(migrationBuilder);
var logEntityBuilder = new LogEntityBuilder(migrationBuilder, ActiveDatabase);
logEntityBuilder.Drop();
//Drop Profile table
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder);
var profileEntityBuilder = new ProfileEntityBuilder(migrationBuilder, ActiveDatabase);
profileEntityBuilder.Drop();
//Drop Setting table
var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder);
var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder, ActiveDatabase);
settingEntityBuilder.Drop();
//Drop Permission table
var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder);
var permissionEntityBuilder = new PermissionEntityBuilder(migrationBuilder, ActiveDatabase);
permissionEntityBuilder.Drop();
//Drop UserRole table
var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder);
var userRoleEntityBuilder = new UserRoleEntityBuilder(migrationBuilder, ActiveDatabase);
userRoleEntityBuilder.Drop();
//Drop Role table
var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder);
var roleEntityBuilder = new RoleEntityBuilder(migrationBuilder, ActiveDatabase);
roleEntityBuilder.Drop();
//Drop User table
var userEntityBuilder = new UserEntityBuilder(migrationBuilder);
var userEntityBuilder = new UserEntityBuilder(migrationBuilder, ActiveDatabase);
userEntityBuilder.Drop();
//Drop PageModule table
var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder);
var pageModuleEntityBuilder = new PageModuleEntityBuilder(migrationBuilder, ActiveDatabase);
pageModuleEntityBuilder.Drop();
//Drop Module table
var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder);
var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder, ActiveDatabase);
moduleEntityBuilder.Drop();
//Drop Page table
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
pageEntityBuilder.Drop();
//Drop Site table
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder);
var siteEntityBuilder = new SiteEntityBuilder(migrationBuilder, ActiveDatabase);
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 Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
@ -7,43 +9,47 @@ namespace Oqtane.Migrations
{
[DbContext(typeof(MasterDBContext))]
[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)
{
//Update Tenant table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.AddIndex("IX_Tenant", "Name");
//Update Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.AddIndex("IX_Alias", "Name");
//Update ModuleDefinitions Table
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder);
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder, ActiveDatabase);
moduleDefinitionsEntityBuilder.AddIndex("IX_ModuleDefinition", "ModuleDefinitionName");
//Update Job Table
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder);
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder, ActiveDatabase);
jobEntityBuilder.AddIndex("IX_Job", "JobType");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
//Update Tenant table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.DropIndex("IX_Tenant");
//Update Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.DropIndex("IX_Alias");
//Update ModuleDefinitions Table
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder);
var moduleDefinitionsEntityBuilder = new ModuleDefinitionsEntityBuilder(migrationBuilder, ActiveDatabase);
moduleDefinitionsEntityBuilder.DropIndex("IX_ModuleDefinition");
//Update Job Table
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder);
var jobEntityBuilder = new JobEntityBuilder(migrationBuilder, ActiveDatabase);
jobEntityBuilder.DropIndex("IX_Job");
}
}

View File

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

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
@ -7,12 +9,16 @@ namespace Oqtane.Migrations
{
[DbContext(typeof(TenantDBContext))]
[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)
{
//Add Column to Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.AddDateTimeColumn("SendOn", true);
migrationBuilder.Sql(
@ -26,7 +32,7 @@ namespace Oqtane.Migrations
protected override void Down(MigrationBuilder migrationBuilder)
{
//Drop Column from Notification table
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder);
var notificationEntityBuilder = new NotificationEntityBuilder(migrationBuilder, ActiveDatabase);
notificationEntityBuilder.DropColumn("SendOn");
}
}

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
@ -7,14 +9,18 @@ namespace Oqtane.Migrations
{
[DbContext(typeof(TenantDBContext))]
[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)
{
//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");
}
}
@ -22,7 +28,7 @@ namespace Oqtane.Migrations
protected override void Down(MigrationBuilder migrationBuilder)
{
//Add Column to Page table
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder, ActiveDatabase);
pageEntityBuilder.AddBooleanColumn("EditMode");
}
}

View File

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

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
@ -7,19 +9,23 @@ namespace Oqtane.Migrations
{
[DbContext(typeof(TenantDBContext))]
[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)
{
//Create Language table
var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder);
var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder, ActiveDatabase);
languageEntityBuilder.Create();
}
protected override void Down(MigrationBuilder migrationBuilder)
{
//Drop Language table
var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder);
var languageEntityBuilder = new LanguageEntityBuilder(migrationBuilder, ActiveDatabase);
languageEntityBuilder.Drop();
}
}

View File

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

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
@ -7,27 +9,31 @@ namespace Oqtane.Migrations
{
[DbContext(typeof(MasterDBContext))]
[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)
{
//Update JobLog table
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder);
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder, ActiveDatabase);
jobLogEntityBuilder.AddIndex("IX_JobLog_JobId", "JobId");
//Update Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.AddIndex("IX_Alias_TenantId", "TenantId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
//Update JobLog table
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder);
var jobLogEntityBuilder = new JobLogEntityBuilder(migrationBuilder, ActiveDatabase);
jobLogEntityBuilder.DropIndex("IX_JobLog_JobId");
//Update Alias table
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder);
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
aliasEntityBuilder.DropIndex("IX_Alias_TenantId");
}
}

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
@ -7,21 +9,28 @@ namespace Oqtane.Migrations
{
[DbContext(typeof(MasterDBContext))]
[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)
{
//Add Column to Site table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder, ActiveDatabase);
tenantEntityBuilder.AddStringColumn("DBType", 200, true);
//Update new column
migrationBuilder.Sql(
@"
//Update new column if SqlServer (Other Databases will not have any records yet)
if (ActiveDatabase.Name == "SqlServer" || ActiveDatabase.Name == "LocalDB")
{
migrationBuilder.Sql(@"
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.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override AliasEntityBuilder BuildTable(ColumnsBuilder table)
{
AliasId = table.AddAutoIncrementColumn("AliasId");
AliasId = ActiveDatabase.AddAutoIncrementColumn(table,"AliasId");
Name = table.AddStringColumn("Name", 200);
TenantId = table.AddIntegerColumn("TenantId");
SiteId = table.AddIntegerColumn("SiteId");

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override AspNetUserClaimsEntityBuilder BuildTable(ColumnsBuilder table)
{
Id = table.AddAutoIncrementColumn("Id");
Id = ActiveDatabase.AddAutoIncrementColumn(table,"Id");
UserId = table.AddStringColumn("UserId", 450);
ClaimType = table.AddMaxStringColumn("ClaimType", true);
ClaimValue = table.AddMaxStringColumn("ClaimValue", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "AspNetUsers";
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;
PrimaryKey = _primaryKey;

View File

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

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable UnusedAutoPropertyAccessor.Global
@ -10,7 +11,7 @@ namespace Oqtane.Migrations.EntityBuilders
{
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.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable MemberCanBePrivate.Global
@ -10,7 +11,7 @@ namespace Oqtane.Migrations.EntityBuilders
{
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.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override FileEntityBuilder BuildTable(ColumnsBuilder table)
{
FileId = table.AddAutoIncrementColumn("FileId");
FileId = ActiveDatabase.AddAutoIncrementColumn(table,"FileId");
FolderId = table.AddIntegerColumn("FolderId");
Name = table.AddStringColumn("Name", 50);
Extension = table.AddStringColumn("Extension", 50);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override FolderEntityBuilder BuildTable(ColumnsBuilder table)
{
FolderId = table.AddAutoIncrementColumn("FolderId");
FolderId = ActiveDatabase.AddAutoIncrementColumn(table,"FolderId");
SiteId = table.AddIntegerColumn("SiteId");
ParentId = table.AddIntegerColumn("ParentId", true);
Name = table.AddStringColumn("Name", 50);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "Job";
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;
PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override JobEntityBuilder BuildTable(ColumnsBuilder table)
{
JobId = table.AddAutoIncrementColumn("JobId");
JobId = ActiveDatabase.AddAutoIncrementColumn(table,"JobId");
Name = table.AddStringColumn("Name", 200);
JobType = table.AddStringColumn("JobType", 200);
Frequency = table.AddStringColumn("Frequency", 1);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.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 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;
PrimaryKey = _primaryKey;
@ -22,7 +23,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override JobLogEntityBuilder BuildTable(ColumnsBuilder table)
{
JobLogId = table.AddAutoIncrementColumn("JobLogId");
JobLogId = ActiveDatabase.AddAutoIncrementColumn(table,"JobLogId");
JobId = table.AddIntegerColumn("JobId");
StartDate = table.AddDateTimeColumn("StartDate");
FinishDate = table.AddDateTimeColumn("FinishDate", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override LanguageEntityBuilder BuildTable(ColumnsBuilder table)
{
LanguageId = table.AddAutoIncrementColumn("LanguageId");
LanguageId = ActiveDatabase.AddAutoIncrementColumn(table,"LanguageId");
SiteId = table.AddIntegerColumn("SiteId");
Name = table.AddStringColumn("Name", 100);
Code = table.AddStringColumn("Code", 10);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override LogEntityBuilder BuildTable(ColumnsBuilder table)
{
LogId = table.AddAutoIncrementColumn("LogId");
LogId = ActiveDatabase.AddAutoIncrementColumn(table,"LogId");
SiteId = table.AddIntegerColumn("SiteId", true);
LogDate = table.AddDateTimeColumn("LogDate");
PageId = table.AddIntegerColumn("PageId", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "ModuleDefinition";
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;
PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override ModuleDefinitionsEntityBuilder BuildTable(ColumnsBuilder table)
{
ModuleDefinitionId = table.AddAutoIncrementColumn("ModuleDefinitionId");
ModuleDefinitionId = ActiveDatabase.AddAutoIncrementColumn(table,"ModuleDefinitionId");
ModuleDefinitionName = table.AddStringColumn("ModuleDefinitionName", 200);
Name = table.AddStringColumn("Name", 200, true);
Description = table.AddStringColumn("Description", 2000, true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override ModuleEntityBuilder BuildTable(ColumnsBuilder table)
{
ModuleId = table.AddAutoIncrementColumn("ModuleId");
ModuleId = ActiveDatabase.AddAutoIncrementColumn(table,"ModuleId");
SiteId = table.AddIntegerColumn("SiteId");
ModuleDefinitionName = table.AddStringColumn("ModuleDefinitionName", 200);
AllPages = table.AddBooleanColumn("AllPages");

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override NotificationEntityBuilder BuildTable(ColumnsBuilder table)
{
NotificationId = table.AddAutoIncrementColumn("NotificationId");
NotificationId = ActiveDatabase.AddAutoIncrementColumn(table,"NotificationId");
SiteId = table.AddIntegerColumn("SiteId");
FromUserId = table.AddIntegerColumn("FromUserId", true);
ToUserId = table.AddIntegerColumn("ToUserId", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,9 +24,16 @@ namespace Oqtane.Migrations.EntityBuilders
protected override PageEntityBuilder BuildTable(ColumnsBuilder table)
{
PageId = table.AddAutoIncrementColumn("PageId");
PageId = ActiveDatabase.AddAutoIncrementColumn(table,"PageId");
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);
Title = table.AddStringColumn("Title", 200, true);
ThemeType = table.AddStringColumn("ThemeType", 200, true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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> _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;
PrimaryKey = _primaryKey;
@ -25,7 +26,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override PageModuleEntityBuilder BuildTable(ColumnsBuilder table)
{
PageModuleId = table.AddAutoIncrementColumn("PageModuleId");
PageModuleId = ActiveDatabase.AddAutoIncrementColumn(table,"PageModuleId");
PageId = table.AddIntegerColumn("PageId");
ModuleId = table.AddIntegerColumn("ModuleId");
Title = table.AddStringColumn("Title", 200);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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> _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;
PrimaryKey = _primaryKey;
@ -27,7 +28,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override PermissionEntityBuilder BuildTable(ColumnsBuilder table)
{
PermissionId = table.AddAutoIncrementColumn("PermissionId");
PermissionId = ActiveDatabase.AddAutoIncrementColumn(table,"PermissionId");
SiteId = table.AddIntegerColumn("SiteId");
EntityName = table.AddStringColumn("EntityName", 50);
EntityId = table.AddIntegerColumn("EntityId");

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override ProfileEntityBuilder BuildTable(ColumnsBuilder table)
{
ProfileId = table.AddAutoIncrementColumn("ProfileId");
ProfileId = ActiveDatabase.AddAutoIncrementColumn(table,"ProfileId");
SiteId = table.AddIntegerColumn("SiteId", true);
Name = table.AddStringColumn("Name", 50);
Title = table.AddStringColumn("Title", 50);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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 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;
PrimaryKey = _primaryKey;
@ -23,7 +24,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override RoleEntityBuilder BuildTable(ColumnsBuilder table)
{
RoleId = table.AddAutoIncrementColumn("RoleId");
RoleId = ActiveDatabase.AddAutoIncrementColumn(table,"RoleId");
SiteId = table.AddIntegerColumn("SiteId", true);
Name = table.AddStringColumn("Name", 256);
Description = table.AddStringColumn("Description", 256);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "Setting";
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;
PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override SettingEntityBuilder BuildTable(ColumnsBuilder table)
{
SettingId = table.AddAutoIncrementColumn("SettingId");
SettingId = ActiveDatabase.AddAutoIncrementColumn(table,"SettingId");
EntityName = table.AddStringColumn("EntityName", 50);
EntityId = table.AddIntegerColumn("EntityId");
SettingName = table.AddStringColumn("SettingName", 50);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "Site";
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;
PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override SiteEntityBuilder BuildTable(ColumnsBuilder table)
{
SiteId = table.AddAutoIncrementColumn("SiteId");
SiteId = ActiveDatabase.AddAutoIncrementColumn(table,"SiteId");
TenantId = table.AddIntegerColumn("TenantId");
Name = table.AddStringColumn("Name", 200);
LogoFileId = table.AddIntegerColumn("LogoFileId", true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "Tenant";
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;
PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override TenantEntityBuilder BuildTable(ColumnsBuilder table)
{
TenantId = table.AddAutoIncrementColumn("TenantId");
TenantId = ActiveDatabase.AddAutoIncrementColumn(table,"TenantId");
Name = table.AddStringColumn("Name", 100);
DBConnectionString = table.AddStringColumn("DBConnectionString", 1024);
Version = table.AddStringColumn("Version", 50, true);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// ReSharper disable MemberCanBePrivate.Global
@ -13,7 +14,7 @@ namespace Oqtane.Migrations.EntityBuilders
private const string _entityTableName = "User";
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;
PrimaryKey = _primaryKey;
@ -21,7 +22,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override UserEntityBuilder BuildTable(ColumnsBuilder table)
{
UserId = table.AddAutoIncrementColumn("UserId");
UserId = ActiveDatabase.AddAutoIncrementColumn(table,"UserId");
Username = table.AddStringColumn("Username", 256);
DisplayName = table.AddStringColumn("DisplayName", 50);
Email = table.AddStringColumn("Email", 256);

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations.Extensions;
// 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> _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;
PrimaryKey = _primaryKey;
@ -25,7 +26,7 @@ namespace Oqtane.Migrations.EntityBuilders
protected override UserRoleEntityBuilder BuildTable(ColumnsBuilder table)
{
UserRoleId = table.AddAutoIncrementColumn("UserRoleId");
UserRoleId = ActiveDatabase.AddAutoIncrementColumn(table,"UserRoleId");
UserId = table.AddIntegerColumn("UserId");
RoleId = table.AddIntegerColumn("RoleId");
EffectiveDate = table.AddDateTimeColumn("EffectiveDate", true);

View File

@ -6,14 +6,6 @@ namespace Oqtane.Migrations.Extensions
{
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)
{
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)
{
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)
{
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.Collections.Generic;
using Oqtane.Infrastructure;
using Oqtane.Models;
using Oqtane.Repository;
@ -8,6 +9,8 @@ using System.Net;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Enums;
using Oqtane.Interfaces;
// ReSharper disable ConvertToUsingDeclaration
namespace Oqtane.Modules.HtmlText.Manager
@ -15,12 +18,12 @@ namespace Oqtane.Modules.HtmlText.Manager
public class HtmlTextManager : MigratableModuleBase, IInstallable, IPortable
{
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;
_sql = sql;
_databases = databases;
}
public string ExportModule(Module module)
@ -54,13 +57,13 @@ namespace Oqtane.Modules.HtmlText.Manager
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);
}
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);
}
}

View File

@ -1,5 +1,8 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Interfaces;
using Oqtane.Migrations;
using Oqtane.Modules.HtmlText.Migrations.EntityBuilders;
using Oqtane.Modules.HtmlText.Repository;
@ -7,19 +10,23 @@ namespace Oqtane.Modules.HtmlText.Migrations
{
[DbContext(typeof(HtmlTextContext))]
[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)
{
//Create HtmlText table
var entityBuilder = new HtmlTextEntityBuilder(migrationBuilder);
var entityBuilder = new HtmlTextEntityBuilder(migrationBuilder, ActiveDatabase);
entityBuilder.Create();
}
protected override void Down(MigrationBuilder migrationBuilder)
{
//Drop HtmlText table
var entityBuilder = new HtmlTextEntityBuilder(migrationBuilder);
var entityBuilder = new HtmlTextEntityBuilder(migrationBuilder, ActiveDatabase);
entityBuilder.Drop();
}
}

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Oqtane.Interfaces;
using Oqtane.Migrations;
using Oqtane.Migrations.EntityBuilders;
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 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;
PrimaryKey = _primaryKey;
@ -25,7 +26,7 @@ namespace Oqtane.Modules.HtmlText.Migrations.EntityBuilders
protected override HtmlTextEntityBuilder BuildTable(ColumnsBuilder table)
{
HtmlTextId = table.AddAutoIncrementColumn("HtmlTextId");
HtmlTextId = ActiveDatabase.AddAutoIncrementColumn(table,"HtmlTextId");
ModuleId = table.AddIntegerColumn("ModuleId");
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.Repository;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Oqtane.Interfaces;
using Oqtane.Repository.Databases.Interfaces;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
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)
{
// ContextBase handles multi-tenant database connections
}
public virtual DbSet<HtmlTextInfo> HtmlText { get; set; }
}
}

View File

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

View File

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

View File

@ -1,20 +1,25 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Oqtane.Interfaces;
namespace Oqtane.Repository
{
public class DbConfig : IDbConfig
{
public DbConfig(IHttpContextAccessor accessor, IConfiguration configuration)
public DbConfig(IHttpContextAccessor accessor, IConfiguration configuration, IEnumerable<IOqtaneDatabase> databases)
{
Accessor = accessor;
Configuration = configuration;
Databases = databases;
}
public IHttpContextAccessor Accessor { get; }
public IConfiguration Configuration { get; }
public IEnumerable<IOqtaneDatabase> Databases { get; set; }
public string ConnectionString { 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.Interfaces;
using Oqtane.Models;
// ReSharper disable CheckNamespace
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace Oqtane.Repository
{
public class InstallationContext : DbContext
{
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;
_databaseType = databaseType;
_database = database;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseOqtaneDatabase(_databaseType, _connectionString);
=> optionsBuilder.UseOqtaneDatabase(_database, _connectionString);
public virtual DbSet<Alias> Alias { get; set; }
public virtual DbSet<Tenant> Tenant { get; set; }

View File

@ -1,9 +1,14 @@
using System;
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Models;
using Microsoft.Extensions.Configuration;
using Oqtane.Extensions;
using Oqtane.Interfaces;
using Oqtane.Migrations.Framework;
using Oqtane.Repository.Databases.Interfaces;
using Oqtane.Shared;
// ReSharper disable BuiltInTypeReferenceStyleForMemberAccess
@ -12,17 +17,22 @@ using Oqtane.Shared;
namespace Oqtane.Repository
{
public class MasterDBContext : DbContext
public class MasterDBContext : DbContext, IMultiDatabase
{
private readonly IDbConfig _dbConfig;
public MasterDBContext(DbContextOptions<MasterDBContext> options, IDbConfig dbConfig) : base(options)
{
_dbConfig = dbConfig;
Databases = dbConfig.Databases;
}
public IEnumerable<IOqtaneDatabase> Databases { get; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.ReplaceService<IMigrationsAssembly, MultiDatabaseMigrationsAssembly>();
var connectionString = _dbConfig.ConnectionString;
var configuration = _dbConfig.Configuration;
var databaseType = _dbConfig.DatabaseType;
@ -38,10 +48,18 @@ namespace Oqtane.Repository
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);
}

View File

@ -1,12 +1,19 @@
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Oqtane.Interfaces;
using Oqtane.Models;
using Oqtane.Repository.Databases.Interfaces;
// ReSharper disable CheckNamespace
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
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<Page> Page { 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<Folder> Folder { get; set; }
public virtual DbSet<File> File { 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.Extensions.Configuration;
using Oqtane.Interfaces;
namespace Oqtane.Repository
{
@ -9,7 +11,10 @@ namespace Oqtane.Repository
public IConfiguration Configuration { get; }
public IEnumerable<IOqtaneDatabase> Databases { get; set; }
public string ConnectionString { get; set; }
public string DatabaseType { get; set; }
}
}

View File

@ -130,10 +130,6 @@ namespace Oqtane
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IDbConfig, DbConfig>();
services.AddDbContext<MasterDBContext>(options => { });
services.AddDbContext<TenantDBContext>(options => { });
services.AddIdentityCore<IdentityUser>(options => { })
.AddEntityFrameworkStores<TenantDBContext>()
.AddSignInManager()
@ -214,6 +210,10 @@ namespace Oqtane
// load the external assemblies into the app domain, install services
services.AddOqtane(_runtime, _supportedCultures);
services.AddScoped<IDbConfig, DbConfig>();
services.AddDbContext<MasterDBContext>(options => { });
services.AddDbContext<TenantDBContext>(options => { });
services.AddMvc()
.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>
<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="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="5.0.1" />
</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>

View File

@ -20,6 +20,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
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
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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}.Release|Any CPU.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE