Add support for Sqlite - Installation path tested but AddSite not supported yet
This commit is contained in:
parent
8f1c760e87
commit
cbcfc88492
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -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
|
||||||
|
|
|
@ -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.
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
using Oqtane.Enums;
|
|
||||||
using Oqtane.Models;
|
|
||||||
|
|
||||||
namespace Oqtane.Infrastructure
|
|
||||||
{
|
|
||||||
public interface IMigratable
|
|
||||||
{
|
|
||||||
bool Migrate(Tenant tenant, MigrationType migrationType);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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'
|
||||||
|
");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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; }
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
Oqtane.Server/Modules/MigratableModuleBase.cs
Normal file
42
Oqtane.Server/Modules/MigratableModuleBase.cs
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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": {
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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";
|
||||||
|
|
Loading…
Reference in New Issue
Block a user