Add support for Sqlite - Installation path tested but AddSite not supported yet

This commit is contained in:
Charles Nurse 2021-03-23 11:06:18 -07:00
parent 8f1c760e87
commit cbcfc88492
22 changed files with 227 additions and 116 deletions

1
.gitignore vendored
View File

@ -13,6 +13,7 @@ msbuild.binlog
Oqtane.Server/appsettings.json Oqtane.Server/appsettings.json
Oqtane.Server/Data/*.mdf Oqtane.Server/Data/*.mdf
Oqtane.Server/Data/*.ldf Oqtane.Server/Data/*.ldf
Oqtane.Server/Data/*.db
/Oqtane.Server/Properties/PublishProfiles/FolderProfile.pubxml /Oqtane.Server/Properties/PublishProfiles/FolderProfile.pubxml
Oqtane.Server/Content Oqtane.Server/Content

View File

@ -27,10 +27,19 @@
<select class="custom-select" @bind="@_databaseType"> <select class="custom-select" @bind="@_databaseType">
<option value="LocalDB">@Localizer["Local Database"]</option> <option value="LocalDB">@Localizer["Local Database"]</option>
<option value="SQLServer">@Localizer["SQL Server"]</option> <option value="SQLServer">@Localizer["SQL Server"]</option>
<option value="Sqlite">@Localizer["Sqlite"]</option>
</select> </select>
</td> </td>
</tr> </tr>
<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> <td>
<label class="control-label" style="font-weight: bold">@Localizer["Server:"] </label> <label class="control-label" style="font-weight: bold">@Localizer["Server:"] </label>
</td> </td>
@ -38,7 +47,7 @@
<input type="text" class="form-control" @bind="@_serverName" /> <input type="text" class="form-control" @bind="@_serverName" />
</td> </td>
</tr> </tr>
<tr> <tr style="@(_databaseType == "Sqlite" ? "display: none" : "")">
<td> <td>
<label class="control-label" style="font-weight: bold">@Localizer["Database:"] </label> <label class="control-label" style="font-weight: bold">@Localizer["Database:"] </label>
</td> </td>
@ -46,7 +55,7 @@
<input type="text" class="form-control" @bind="@_databaseName" /> <input type="text" class="form-control" @bind="@_databaseName" />
</td> </td>
</tr> </tr>
<tr> <tr style="@(_databaseType == "Sqlite" ? "display: none" : "")">
<td> <td>
<label class="control-label" style="font-weight: bold">@Localizer["Integrated Security:"] </label> <label class="control-label" style="font-weight: bold">@Localizer["Integrated Security:"] </label>
</td> </td>
@ -129,6 +138,7 @@
@code { @code {
private string _databaseType = "LocalDB"; private string _databaseType = "LocalDB";
private string _serverName = "(LocalDb)\\MSSQLLocalDB"; private string _serverName = "(LocalDb)\\MSSQLLocalDB";
private string _fileName = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm") + ".db";
private string _databaseName = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm"); private string _databaseName = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm");
private string _username = string.Empty; private string _username = string.Empty;
private string _password = string.Empty; private string _password = string.Empty;
@ -138,6 +148,8 @@
private string _hostEmail = string.Empty; private string _hostEmail = string.Empty;
private string _message = string.Empty; private string _message = string.Empty;
private string _integratedSecurityDisplay = "display: none;"; private string _integratedSecurityDisplay = "display: none;";
private string _fileFieldsDisplay = "display: none;";
private string _serverFieldsDisplay = "display: none;";
private string _loadingDisplay = "display: none;"; private string _loadingDisplay = "display: none;";
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
@ -158,33 +170,38 @@
private async Task Install() private async Task Install()
{ {
if (_serverName != "" && _databaseName != "" && _hostUsername != "" && _hostPassword.Length >= 6 && _hostPassword == _confirmPassword && _hostEmail != "") if (((_serverName != "" && _databaseName != "") || _fileName !="") && _hostUsername != "" && _hostPassword.Length >= 6 && _hostPassword == _confirmPassword && _hostEmail != "")
{ {
_loadingDisplay = ""; _loadingDisplay = "";
StateHasChanged(); StateHasChanged();
var connectionstring = ""; var connectionstring = "";
if (_databaseType == "LocalDB") switch (_databaseType)
{ {
connectionstring = "Data Source=" + _serverName + ";AttachDbFilename=|DataDirectory|\\" + _databaseName + ".mdf;Initial Catalog=" + _databaseName + ";Integrated Security=SSPI;"; case "LocalDB":
} connectionstring = "Data Source=" + _serverName + ";AttachDbFilename=|DataDirectory|\\" + _databaseName + ".mdf;Initial Catalog=" + _databaseName + ";Integrated Security=SSPI;";
else break;
{ case "SQLServer":
connectionstring = "Data Source=" + _serverName + ";Initial Catalog=" + _databaseName + ";"; connectionstring = "Data Source=" + _serverName + ";Initial Catalog=" + _databaseName + ";";
if (_integratedSecurityDisplay == "display: none;") if (_integratedSecurityDisplay == "display: none;")
{ {
connectionstring += "Integrated Security=SSPI;"; connectionstring += "Integrated Security=SSPI;";
} }
else else
{ {
connectionstring += "User ID=" + _username + ";Password=" + _password; connectionstring += "User ID=" + _username + ";Password=" + _password;
} }
break;
case "Sqlite":
connectionstring = "Data Source=" + _fileName;
break;
} }
Uri uri = new Uri(NavigationManager.Uri); Uri uri = new Uri(NavigationManager.Uri);
var config = new InstallConfig var config = new InstallConfig
{ {
DatabaseType = _databaseType,
ConnectionString = connectionstring, ConnectionString = connectionstring,
Aliases = uri.Authority, Aliases = uri.Authority,
HostEmail = _hostEmail, HostEmail = _hostEmail,

Binary file not shown.

View File

@ -5,10 +5,18 @@ namespace Oqtane.Extensions
{ {
public static class DbContextOptionsBuilderExtensions public static class DbContextOptionsBuilderExtensions
{ {
public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, string connectionString) public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, string databaseType, string connectionString)
{ {
optionsBuilder.UseSqlServer(connectionString); switch (databaseType)
//optionsBuilder.UseSqlite("Data Source=Oqtane.db"); {
case "SqlServer":
optionsBuilder.UseSqlServer(connectionString);
break;
case "Sqlite":
optionsBuilder.UseSqlite(connectionString);
break;
}
return optionsBuilder; return optionsBuilder;
} }

View File

@ -171,7 +171,8 @@ namespace Oqtane.Infrastructure
if (!Directory.Exists(dataDirectory)) Directory.CreateDirectory(dataDirectory ?? String.Empty); if (!Directory.Exists(dataDirectory)) Directory.CreateDirectory(dataDirectory ?? String.Empty);
var connectionString = NormalizeConnectionString(install.ConnectionString); var connectionString = NormalizeConnectionString(install.ConnectionString);
using (var dbc = new DbContext(new DbContextOptionsBuilder().UseOqtaneDatabase(connectionString).Options)) var databaseType = install.DatabaseType;
using (var dbc = new DbContext(new DbContextOptionsBuilder().UseOqtaneDatabase(databaseType, connectionString).Options))
{ {
// create empty database if it does not exist // create empty database if it does not exist
dbc.Database.EnsureCreated(); dbc.Database.EnsureCreated();
@ -199,7 +200,7 @@ namespace Oqtane.Infrastructure
{ {
try try
{ {
var dbConfig = new DbConfig(null, null) {ConnectionString = install.ConnectionString}; var dbConfig = new DbConfig(null, null) {ConnectionString = install.ConnectionString, DatabaseType = install.DatabaseType};
using (var masterDbContext = new MasterDBContext(new DbContextOptions<MasterDBContext>(), dbConfig)) using (var masterDbContext = new MasterDBContext(new DbContextOptions<MasterDBContext>(), dbConfig))
{ {
@ -216,6 +217,7 @@ namespace Oqtane.Infrastructure
if (result.Success) if (result.Success)
{ {
UpdateConnectionString(install.ConnectionString); UpdateConnectionString(install.ConnectionString);
UpdateDatabaseType(install.DatabaseType);
} }
} }
else else
@ -232,12 +234,18 @@ namespace Oqtane.Infrastructure
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases)) if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases))
{ {
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey)))) using (var db = new InstallationContext(install.DatabaseType, NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
{ {
Tenant tenant; Tenant tenant;
if (install.IsNewTenant) if (install.IsNewTenant)
{ {
tenant = new Tenant { Name = install.TenantName, DBConnectionString = DenormalizeConnectionString(install.ConnectionString), CreatedBy = "", CreatedOn = DateTime.UtcNow, ModifiedBy = "", ModifiedOn = DateTime.UtcNow }; 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.Tenant.Add(tenant);
db.SaveChanges(); db.SaveChanges();
_cache.Remove("tenants"); _cache.Remove("tenants");
@ -276,13 +284,15 @@ namespace Oqtane.Infrastructure
{ {
var upgrades = scope.ServiceProvider.GetRequiredService<IUpgradeManager>(); var upgrades = scope.ServiceProvider.GetRequiredService<IUpgradeManager>();
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey)))) var databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey];
var connectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey));
using (var db = new InstallationContext(databaseType, connectionString))
{ {
foreach (var tenant in db.Tenant.ToList()) foreach (var tenant in db.Tenant.ToList())
{ {
try try
{ {
var dbConfig = new DbConfig(null, null) {ConnectionString = install.ConnectionString}; var dbConfig = new DbConfig(null, null) {ConnectionString = install.ConnectionString, DatabaseType = install.DatabaseType};
using (var tenantDbContext = new TenantDBContext(dbConfig, null)) using (var tenantDbContext = new TenantDBContext(dbConfig, null))
{ {
// Push latest model into database // Push latest model into database
@ -337,44 +347,37 @@ namespace Oqtane.Infrastructure
if (moduleType != null) if (moduleType != null)
{ {
var versions = moduleDefinition.ReleaseVersions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var versions = moduleDefinition.ReleaseVersions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey)))) var databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey];
{ var connectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey));
using (var db = new InstallationContext(databaseType, connectionString)) {
foreach (var tenant in db.Tenant.ToList()) foreach (var tenant in db.Tenant.ToList())
{ {
if (moduleType.GetInterface("IMigratable") != null) var index = Array.FindIndex(versions, item => item == moduleDefinition.Version);
if (tenant.Name == install.TenantName && install.TenantName != TenantNames.Master)
{ {
var moduleObject = ActivatorUtilities.CreateInstance(scope.ServiceProvider, moduleType) as IMigratable; index = -1;
moduleObject.Migrate(tenant, MigrationType.Up);
} }
else if (index != (versions.Length - 1))
{ {
var index = Array.FindIndex(versions, item => item == moduleDefinition.Version); if (index == -1) index = 0;
if (tenant.Name == install.TenantName && install.TenantName != TenantNames.Master) for (var i = index; i < versions.Length; i++)
{ {
index = -1; try
}
if (index != (versions.Length - 1))
{
if (index == -1) index = 0;
for (var i = index; i < versions.Length; i++)
{ {
try if (moduleType.GetInterface("IInstallable") != null)
{ {
if (moduleType.GetInterface("IInstallable") != null) var moduleObject = ActivatorUtilities.CreateInstance(scope.ServiceProvider, moduleType) as IInstallable;
{ moduleObject?.Install(tenant, versions[i]);
var moduleObject = ActivatorUtilities.CreateInstance(scope.ServiceProvider, moduleType);
((IInstallable)moduleObject).Install(tenant, versions[i]);
}
else
{
sql.ExecuteScript(tenant, moduleType.Assembly, Utilities.GetTypeName(moduleDefinition.ModuleDefinitionName) + "." + versions[i] + ".sql");
}
} }
catch (Exception ex) else
{ {
result.Message = "An Error Occurred Installing " + moduleDefinition.Name + " Version " + versions[i] + " - " + ex.Message; sql.ExecuteScript(tenant, moduleType.Assembly, Utilities.GetTypeName(moduleDefinition.ModuleDefinitionName) + "." + versions[i] + ".sql");
} }
} }
catch (Exception ex)
{
result.Message = "An Error Occurred Installing " + moduleDefinition.Name + " Version " + versions[i] + " - " + ex.Message;
}
} }
} }
} }
@ -530,11 +533,17 @@ namespace Oqtane.Infrastructure
connectionString = DenormalizeConnectionString(connectionString); connectionString = DenormalizeConnectionString(connectionString);
if (_config.GetConnectionString(SettingKeys.ConnectionStringKey) != connectionString) if (_config.GetConnectionString(SettingKeys.ConnectionStringKey) != connectionString)
{ {
AddOrUpdateAppSetting($"ConnectionStrings:{SettingKeys.ConnectionStringKey}", connectionString); AddOrUpdateAppSetting($"{SettingKeys.ConnectionStringsSection}:{SettingKeys.ConnectionStringKey}", connectionString);
_config.Reload(); _config.Reload();
} }
} }
public void UpdateDatabaseType(string databaseType)
{
AddOrUpdateAppSetting($"{SettingKeys.DatabaseSection}:{SettingKeys.DatabaseTypeKey}", databaseType);
_config.Reload();
}
public void AddOrUpdateAppSetting<T>(string sectionPathKey, T value) public void AddOrUpdateAppSetting<T>(string sectionPathKey, T value)
{ {
try try

View File

@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Oqtane.Shared; using Oqtane.Shared;
// ReSharper disable AssignNullToNotNullAttribute
namespace Oqtane.Infrastructure namespace Oqtane.Infrastructure
{ {

View File

@ -1,10 +0,0 @@
using Oqtane.Enums;
using Oqtane.Models;
namespace Oqtane.Infrastructure
{
public interface IMigratable
{
bool Migrate(Tenant tenant, MigrationType migrationType);
}
}

View File

@ -21,6 +21,12 @@ namespace Oqtane.Migrations
pageEntityBuilder.Create(); pageEntityBuilder.Create();
pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true); pageEntityBuilder.AddIndex("IX_Page", new [] {"SiteId", "Path", "UserId"}, true);
//Add Column to Page table (for Sql Server only) we will drop it later for Sql Server only
if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.SqlServer")
{
pageEntityBuilder.AddBooleanColumn("EditMode");
}
//Create Module table //Create Module table
var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder); var moduleEntityBuilder = new ModuleEntityBuilder(migrationBuilder);
moduleEntityBuilder.Create(); moduleEntityBuilder.Create();

View File

@ -12,7 +12,7 @@ namespace Oqtane.Migrations
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
//Drop Column from Page table //Drop Column from Page table
if (migrationBuilder.ActiveProvider != "Microsoft.EntityFrameworkCore.Sqlite") if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.SqlServer")
{ {
var pageEntityBuilder = new PageEntityBuilder(migrationBuilder); var pageEntityBuilder = new PageEntityBuilder(migrationBuilder);
pageEntityBuilder.DropColumn("EditMode"); pageEntityBuilder.DropColumn("EditMode");

View File

@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Migrations.EntityBuilders;
using Oqtane.Repository;
namespace Oqtane.Migrations
{
[DbContext(typeof(MasterDBContext))]
[Migration("Master.02.01.00.01")]
public class AddDatabaseTypeColumnToTenant : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
//Add Column to Site table
var tenantEntityBuilder = new TenantEntityBuilder(migrationBuilder);
tenantEntityBuilder.AddStringColumn("DBType", 200, true);
//Update new column
migrationBuilder.Sql(
@"
UPDATE Tenant
SET DBType = 'SqlServer'
");
}
}
}

View File

@ -35,7 +35,6 @@ namespace Oqtane.Migrations.EntityBuilders
IsNavigation = table.AddBooleanColumn("IsNavigation"); IsNavigation = table.AddBooleanColumn("IsNavigation");
Url = table.AddStringColumn("Url", 500, true); Url = table.AddStringColumn("Url", 500, true);
LayoutType = table.AddStringColumn("LayoutType", 200); LayoutType = table.AddStringColumn("LayoutType", 200);
EditMode = table.AddBooleanColumn("EditMode");
UserId = table.AddIntegerColumn("UserId", true); UserId = table.AddIntegerColumn("UserId", true);
IsPersonalizable = table.AddBooleanColumn("IsPersonalizable"); IsPersonalizable = table.AddBooleanColumn("IsPersonalizable");
DefaultContainerType = table.AddStringColumn("DefaultContainerType", 200, true); DefaultContainerType = table.AddStringColumn("DefaultContainerType", 200, true);
@ -69,8 +68,6 @@ namespace Oqtane.Migrations.EntityBuilders
public OperationBuilder<AddColumnOperation> LayoutType { get; private set; } public OperationBuilder<AddColumnOperation> LayoutType { get; private set; }
public OperationBuilder<AddColumnOperation> EditMode { get; private set; }
public OperationBuilder<AddColumnOperation> UserId { get; private set; } public OperationBuilder<AddColumnOperation> UserId { get; private set; }
public OperationBuilder<AddColumnOperation> IsPersonalizable { get; private set; } public OperationBuilder<AddColumnOperation> IsPersonalizable { get; private set; }

View File

@ -12,7 +12,7 @@ using Oqtane.Enums;
namespace Oqtane.Modules.HtmlText.Manager namespace Oqtane.Modules.HtmlText.Manager
{ {
public class HtmlTextManager : IMigratable, IPortable public class HtmlTextManager : MigratableModuleBase, IInstallable, IPortable
{ {
private readonly IHtmlTextRepository _htmlText; private readonly IHtmlTextRepository _htmlText;
private readonly ISqlRepository _sql; private readonly ISqlRepository _sql;
@ -23,35 +23,6 @@ namespace Oqtane.Modules.HtmlText.Manager
_sql = sql; _sql = sql;
} }
public bool Migrate(Tenant tenant, MigrationType migrationType)
{
var result = true;
var dbConfig = new DbConfig(null, null) {ConnectionString = tenant.DBConnectionString};
using (var db = new HtmlTextContext(dbConfig, null))
{
try
{
var migrator = db.GetService<IMigrator>();
if (migrationType == MigrationType.Down)
{
migrator.Migrate(Migration.InitialDatabase);
}
else
{
migrator.Migrate();
}
}
catch (Exception e)
{
Console.WriteLine(e);
result = false;
}
}
return result;
}
public string ExportModule(Module module) public string ExportModule(Module module)
{ {
string content = ""; string content = "";
@ -80,5 +51,17 @@ namespace Oqtane.Modules.HtmlText.Manager
_htmlText.AddHtmlText(htmlText); _htmlText.AddHtmlText(htmlText);
} }
} }
public bool Install(Tenant tenant, string version)
{
var dbConfig = new DbConfig(null, null) {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};
return Migrate(new HtmlTextContext(dbConfig, null), tenant, MigrationType.Down);
}
} }
} }

View File

@ -0,0 +1,42 @@
using System;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Oqtane.Enums;
using Oqtane.Models;
using Oqtane.Modules.HtmlText.Repository;
using Oqtane.Repository;
namespace Oqtane.Modules
{
public class MigratableModuleBase
{
public bool Migrate(DBContextBase dbContext, Tenant tenant, MigrationType migrationType)
{
var result = true;
using (dbContext)
{
try
{
var migrator = dbContext.GetService<IMigrator>();
if (migrationType == MigrationType.Down)
{
migrator.Migrate(Migration.InitialDatabase);
}
else
{
migrator.Migrate();
}
}
catch (Exception e)
{
Console.WriteLine(e);
result = false;
}
}
return result;
}
}
}

View File

@ -7,48 +7,62 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Oqtane.Extensions; using Oqtane.Extensions;
using Oqtane.Models; using Oqtane.Models;
using Oqtane.Shared;
// ReSharper disable BuiltInTypeReferenceStyleForMemberAccess // ReSharper disable BuiltInTypeReferenceStyleForMemberAccess
namespace Oqtane.Repository namespace Oqtane.Repository
{ {
public class DBContextBase : IdentityUserContext<IdentityUser> public class DBContextBase : IdentityUserContext<IdentityUser>
{ {
private readonly IDbConfig _dbConfig;
private readonly ITenantResolver _tenantResolver; private readonly ITenantResolver _tenantResolver;
private readonly IHttpContextAccessor _accessor;
private readonly IConfiguration _configuration;
private string _connectionString;
private string _databaseType;
public DBContextBase(ITenantResolver tenantResolver, IHttpContextAccessor httpContextAccessor)
{
_connectionString = String.Empty;
_tenantResolver = tenantResolver;
_accessor = httpContextAccessor;
}
public DBContextBase(IDbConfig dbConfig, ITenantResolver tenantResolver) public DBContextBase(IDbConfig dbConfig, ITenantResolver tenantResolver)
{ {
_dbConfig = dbConfig; _accessor = dbConfig.Accessor;
_configuration = dbConfig.Configuration;
_connectionString = dbConfig.ConnectionString;
_databaseType = dbConfig.DatabaseType;
_tenantResolver = tenantResolver; _tenantResolver = tenantResolver;
} }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ {
var connectionString = _dbConfig.ConnectionString; if (string.IsNullOrEmpty(_connectionString) && _tenantResolver != null)
if (string.IsNullOrEmpty(connectionString) && _tenantResolver != null)
{ {
var tenant = _tenantResolver.GetTenant(); var tenant = _tenantResolver.GetTenant();
var configuration = _dbConfig.Configuration;
if (tenant != null) if (tenant != null)
{ {
connectionString = tenant.DBConnectionString _connectionString = tenant.DBConnectionString
.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString()); .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString());
_databaseType = tenant.DBType;
} }
else else
{ {
if (!String.IsNullOrEmpty(configuration.GetConnectionString("DefaultConnection"))) if (!String.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))
{ {
connectionString = configuration.GetConnectionString("DefaultConnection") _connectionString = _configuration.GetConnectionString("DefaultConnection")
.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString()); .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString());
} }
_databaseType = _configuration.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey];
} }
} }
if (!string.IsNullOrEmpty(connectionString)) if (!string.IsNullOrEmpty(_connectionString) && !string.IsNullOrEmpty(_databaseType))
{ {
optionsBuilder.UseOqtaneDatabase(connectionString); optionsBuilder.UseOqtaneDatabase(_databaseType, _connectionString);
} }
base.OnConfiguring(optionsBuilder); base.OnConfiguring(optionsBuilder);
@ -56,7 +70,7 @@ namespace Oqtane.Repository
public override int SaveChanges() public override int SaveChanges()
{ {
DbContextUtils.SaveChanges(this, _dbConfig.Accessor); DbContextUtils.SaveChanges(this, _accessor);
return base.SaveChanges(); return base.SaveChanges();
} }

View File

@ -16,5 +16,7 @@ namespace Oqtane.Repository
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }
public string ConnectionString { get; set; } public string ConnectionString { get; set; }
public string DatabaseType { get; set; }
} }
} }

View File

@ -9,14 +9,16 @@ namespace Oqtane.Repository
public class InstallationContext : DbContext public class InstallationContext : DbContext
{ {
private readonly string _connectionString; private readonly string _connectionString;
private readonly string _databaseType;
public InstallationContext(string connectionString) public InstallationContext(string databaseType, string connectionString)
{ {
_connectionString = connectionString; _connectionString = connectionString;
_databaseType = databaseType;
} }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseOqtaneDatabase(_connectionString); => optionsBuilder.UseOqtaneDatabase(_databaseType, _connectionString);
public virtual DbSet<Alias> Alias { get; set; } public virtual DbSet<Alias> Alias { get; set; }
public virtual DbSet<Tenant> Tenant { get; set; } public virtual DbSet<Tenant> Tenant { get; set; }

View File

@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Oqtane.Models; using Oqtane.Models;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Oqtane.Extensions; using Oqtane.Extensions;
using Oqtane.Shared;
// ReSharper disable BuiltInTypeReferenceStyleForMemberAccess // ReSharper disable BuiltInTypeReferenceStyleForMemberAccess
// ReSharper disable UnusedAutoPropertyAccessor.Global // ReSharper disable UnusedAutoPropertyAccessor.Global
@ -24,6 +25,7 @@ namespace Oqtane.Repository
{ {
var connectionString = _dbConfig.ConnectionString; var connectionString = _dbConfig.ConnectionString;
var configuration = _dbConfig.Configuration; var configuration = _dbConfig.Configuration;
var databaseType = _dbConfig.DatabaseType;
if(string.IsNullOrEmpty(connectionString) && configuration != null) if(string.IsNullOrEmpty(connectionString) && configuration != null)
{ {
@ -33,11 +35,12 @@ namespace Oqtane.Repository
.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString()); .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString());
} }
databaseType = configuration.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey];
} }
if (!string.IsNullOrEmpty(connectionString)) if (!string.IsNullOrEmpty(connectionString))
{ {
optionsBuilder.UseOqtaneDatabase(connectionString); optionsBuilder.UseOqtaneDatabase(databaseType, connectionString);
} }
base.OnConfiguring(optionsBuilder); base.OnConfiguring(optionsBuilder);
} }

View File

@ -10,5 +10,6 @@ namespace Oqtane.Repository
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }
public string ConnectionString { get; set; } public string ConnectionString { get; set; }
public string DatabaseType { get; set; }
} }
} }

View File

@ -1,10 +1,10 @@
{ {
"Database": { "Database": {
"DatabaseType": "", "DatabaseType": "Sqlite",
"DatabaseEngineVersion": "" "DatabaseEngineVersion": ""
}, },
"ConnectionStrings": { "ConnectionStrings": {
"DefaultConnection": "Data Source=.;Initial Catalog=Oqtane-Migrations;Integrated Security=SSPI;" "DefaultConnection": "Data Source=Oqtane.db"
}, },
"Runtime": "Server", "Runtime": "Server",
"Installation": { "Installation": {

View File

@ -7,6 +7,7 @@ namespace Oqtane.Models
public int TenantId { get; set; } public int TenantId { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string DBConnectionString { get; set; } public string DBConnectionString { get; set; }
public string DBType { get; set; }
public string Version { get; set; } public string Version { get; set; }
public string CreatedBy { get; set; } public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; } public DateTime CreatedOn { get; set; }

View File

@ -3,6 +3,7 @@ namespace Oqtane.Shared
public class InstallConfig public class InstallConfig
{ {
public string ConnectionString { get; set; } public string ConnectionString { get; set; }
public string DatabaseType { get; set; }
public string Aliases { get; set; } public string Aliases { get; set; }
public string TenantName { get; set; } public string TenantName { get; set; }
public bool IsNewTenant { get; set; } public bool IsNewTenant { get; set; }

View File

@ -2,12 +2,18 @@
{ {
public static class SettingKeys public static class SettingKeys
{ {
public const string ConnectionStringsSection = "ConnectionStrings";
public const string DatabaseSection = "Database";
public const string InstallationSection = "Installation"; public const string InstallationSection = "Installation";
public const string ConnectionStringKey = "DefaultConnection";
public const string DatabaseTypeKey = "DatabaseType";
public const string DefaultAliasKey = "DefaultAlias"; public const string DefaultAliasKey = "DefaultAlias";
public const string HostPasswordKey = "HostPassword"; public const string HostPasswordKey = "HostPassword";
public const string HostEmailKey = "HostEmail"; public const string HostEmailKey = "HostEmail";
public const string SiteTemplateKey = "SiteTemplate"; public const string SiteTemplateKey = "SiteTemplate";
public const string ConnectionStringKey = "DefaultConnection";
public const string DefaultThemeKey = "DefaultTheme"; public const string DefaultThemeKey = "DefaultTheme";
public const string DefaultLayoutKey = "DefaultLayout"; public const string DefaultLayoutKey = "DefaultLayout";
public const string DefaultContainerKey = "DefaultContainer"; public const string DefaultContainerKey = "DefaultContainer";