diff --git a/Oqtane.Client/Installer/Installer.razor b/Oqtane.Client/Installer/Installer.razor
index 019e12d5..968c582e 100644
--- a/Oqtane.Client/Installer/Installer.razor
+++ b/Oqtane.Client/Installer/Installer.razor
@@ -31,7 +31,7 @@
{
foreach (var database in _databases)
{
-
+
}
}
@@ -174,7 +174,6 @@
var config = new InstallConfig
{
DatabaseType = database.DBType,
- DatabasePackage = database.Package,
ConnectionString = connectionString,
Aliases = uri.Authority,
HostEmail = _hostEmail,
diff --git a/Oqtane.Client/Modules/Admin/Sites/Add.razor b/Oqtane.Client/Modules/Admin/Sites/Add.razor
index 9a93ab17..832f1b33 100644
--- a/Oqtane.Client/Modules/Admin/Sites/Add.razor
+++ b/Oqtane.Client/Modules/Admin/Sites/Add.razor
@@ -130,7 +130,7 @@ else
@@ -305,7 +305,6 @@ else
{
config.TenantName = _tenantName;
config.DatabaseType = database.DBType;
- config.DatabasePackage = database.Package;
config.ConnectionString = connectionString;
config.HostEmail = user.Email;
config.HostPassword = _hostpassword;
diff --git a/Oqtane.Client/Services/DatabaseService.cs b/Oqtane.Client/Services/DatabaseService.cs
index 5f9aa925..81c93248 100644
--- a/Oqtane.Client/Services/DatabaseService.cs
+++ b/Oqtane.Client/Services/DatabaseService.cs
@@ -24,7 +24,7 @@ namespace Oqtane.Services
public async Task> GetDatabasesAsync()
{
List databases = await GetJsonAsync>(Apiurl);
- return databases.OrderBy(item => item.FriendlyName).ToList();
+ return databases.OrderBy(item => item.Name).ToList();
}
}
}
diff --git a/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs
index fe7cd083..a35ecf77 100644
--- a/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs
+++ b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs
@@ -1,8 +1,6 @@
-using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
using Oqtane.Databases.Interfaces;
-using Oqtane.Interfaces;
// ReSharper disable ConvertToUsingDeclaration
namespace Oqtane.Extensions
diff --git a/Oqtane.Server/Infrastructure/ConfigManager.cs b/Oqtane.Server/Infrastructure/ConfigManager.cs
new file mode 100644
index 00000000..196b2087
--- /dev/null
+++ b/Oqtane.Server/Infrastructure/ConfigManager.cs
@@ -0,0 +1,102 @@
+using System;
+using System.IO;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Oqtane.Infrastructure
+{
+ public class ConfigManager : IConfigManager
+ {
+ private readonly IConfigurationRoot _config;
+
+ public ConfigManager(IConfigurationRoot config)
+ {
+ _config = config;
+ }
+
+ public IConfigurationSection GetSection(string key)
+ {
+ return _config.GetSection(key);
+ }
+
+ public string GetSetting(string sectionKey, string settingKey, string defaultValue)
+ {
+ var value = _config.GetSection(sectionKey).GetValue(settingKey, defaultValue);
+ if (string.IsNullOrEmpty(value)) value = defaultValue;
+ return value;
+ }
+
+ public void AddOrUpdateSetting(string key, T value, bool reload)
+ {
+ AddOrUpdateSetting("appsettings.json", key, value, reload);
+ }
+
+ public void AddOrUpdateSetting(string file, string key, T value, bool reload)
+ {
+ try
+ {
+ var path = Path.Combine(Directory.GetCurrentDirectory(), file);
+ dynamic jsonObj = JsonConvert.DeserializeObject(File.ReadAllText(path));
+ SetValueRecursively(key, jsonObj, value, "set");
+ File.WriteAllText(path, JsonConvert.SerializeObject(jsonObj, Formatting.Indented));
+ if (reload) Reload();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Error modifying app settings {0}", ex);
+ }
+ }
+
+ public void RemoveSetting(string key, bool reload)
+ {
+ RemoveSetting("appsettings.json", key, reload);
+ }
+
+ public void RemoveSetting(string file, string key, bool reload)
+ {
+ try
+ {
+ var path = Path.Combine(Directory.GetCurrentDirectory(), file);
+ dynamic jsonObj = JsonConvert.DeserializeObject(File.ReadAllText(path));
+ SetValueRecursively(key, jsonObj, "", "remove");
+ File.WriteAllText(path, JsonConvert.SerializeObject(jsonObj, Formatting.Indented));
+ if (reload) Reload();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Error modifying app settings {0}", ex);
+ }
+ }
+
+ private void SetValueRecursively(string key, dynamic jsonObj, T value, string action)
+ {
+ var remainingSections = key.Split(":", 2);
+
+ var currentSection = remainingSections[0];
+ if (remainingSections.Length > 1)
+ {
+ var nextSection = remainingSections[1];
+ jsonObj[currentSection] ??= new JObject();
+ SetValueRecursively(nextSection, jsonObj[currentSection], value, action);
+ }
+ else
+ {
+ switch (action)
+ {
+ case "set":
+ jsonObj[currentSection] = value;
+ break;
+ case "remove":
+ jsonObj.Property(currentSection).Remove();
+ break;
+ }
+ }
+ }
+
+ public void Reload()
+ {
+ _config.Reload();
+ }
+ }
+}
diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs
index 986aa4ca..a7030c6a 100644
--- a/Oqtane.Server/Infrastructure/DatabaseManager.cs
+++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs
@@ -10,14 +10,13 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
using Oqtane.Databases.Interfaces;
using Oqtane.Extensions;
using Oqtane.Models;
using Oqtane.Repository;
using Oqtane.Shared;
using Oqtane.Enums;
-using File = System.IO.File;
+using Newtonsoft.Json;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable ConvertToUsingDeclaration
@@ -32,18 +31,23 @@ namespace Oqtane.Infrastructure
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IWebHostEnvironment _environment;
private readonly IMemoryCache _cache;
+ private readonly IConfigManager _configManager;
- public DatabaseManager(IConfigurationRoot config, IServiceScopeFactory serviceScopeFactory, IWebHostEnvironment environment, IMemoryCache cache)
+ public DatabaseManager(IConfigurationRoot config, IServiceScopeFactory serviceScopeFactory, IWebHostEnvironment environment, IMemoryCache cache, IConfigManager configManager)
{
_config = config;
_serviceScopeFactory = serviceScopeFactory;
_environment = environment;
_cache = cache;
+ _configManager = configManager;
}
public Installation IsInstalled()
{
var result = new Installation { Success = false, Message = string.Empty };
+
+ ValidateConfiguration();
+
if (!string.IsNullOrEmpty(_config.GetConnectionString(SettingKeys.ConnectionStringKey)))
{
result.Success = true;
@@ -97,7 +101,6 @@ namespace Oqtane.Infrastructure
if (string.IsNullOrEmpty(install.DatabaseType))
{
install.DatabaseType = Constants.DefaultDBType;
- install.DatabasePackage = Constants.DefaultDBType.Substring(Constants.DefaultDBType.IndexOf(",") + 2);
InstallDatabase(install);
UpdateDatabaseType(install.DatabaseType);
}
@@ -106,7 +109,6 @@ namespace Oqtane.Infrastructure
// if database type does not exist, install the associated Nuget package
if (Type.GetType(install.DatabaseType) == null)
{
- install.DatabasePackage = install.DatabaseType.Substring(install.DatabaseType.IndexOf(",") + 2);
InstallDatabase(install);
}
}
@@ -220,7 +222,7 @@ namespace Oqtane.Infrastructure
// iterate through Nuget packages in source folder
foreach (var package in packagesFolder.GetFiles("*.nupkg.bak"))
{
- if (package.Name.StartsWith(install.DatabasePackage))
+ if (package.Name.StartsWith(Utilities.GetAssemblyName(install.DatabaseType)))
{
//rename file
var packageName = Path.Combine(package.DirectoryName, package.Name);
@@ -237,7 +239,7 @@ namespace Oqtane.Infrastructure
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
var assembliesFolder = new DirectoryInfo(assemblyPath);
- var assemblyFile = new FileInfo($"{assembliesFolder}/{install.DatabasePackage}.dll");
+ var assemblyFile = new FileInfo($"{assembliesFolder}/{Utilities.GetAssemblyName(install.DatabaseType)}.dll");
AssemblyLoadContext.Default.LoadOqtaneAssembly(assemblyFile);
@@ -644,25 +646,6 @@ namespace Oqtane.Infrastructure
return result;
}
- public void AddOrUpdateAppSetting(string sectionPathKey, T value)
- {
- try
- {
- var filePath = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
- var json = File.ReadAllText(filePath);
- dynamic jsonObj = JsonConvert.DeserializeObject(json);
-
- SetValueRecursively(sectionPathKey, jsonObj, value);
-
- string output = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
- File.WriteAllText(filePath, output);
- }
- catch (Exception ex)
- {
- Console.WriteLine("Error writing app settings | {0}", ex);
- }
- }
-
private string DenormalizeConnectionString(string connectionString)
{
var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString();
@@ -687,10 +670,7 @@ namespace Oqtane.Infrastructure
private string GetInstallationConfig(string key, string defaultValue)
{
- var value = _config.GetSection(SettingKeys.InstallationSection).GetValue(key, defaultValue);
- // double fallback to default value - allow hold sample keys in config
- if (string.IsNullOrEmpty(value)) value = defaultValue;
- return value;
+ return _configManager.GetSetting(SettingKeys.InstallationSection, key, defaultValue);
}
private string NormalizeConnectionString(string connectionString)
@@ -700,39 +680,18 @@ namespace Oqtane.Infrastructure
return connectionString;
}
- private void SetValueRecursively(string sectionPathKey, dynamic jsonObj, T value)
- {
- // split the string at the first ':' character
- var remainingSections = sectionPathKey.Split(":", 2);
-
- var currentSection = remainingSections[0];
- if (remainingSections.Length > 1)
- {
- // continue with the process, moving down the tree
- var nextSection = remainingSections[1];
- SetValueRecursively(nextSection, jsonObj[currentSection], value);
- }
- else
- {
- // we've got to the end of the tree, set the value
- jsonObj[currentSection] = value;
- }
- }
-
public void UpdateConnectionString(string connectionString)
{
connectionString = DenormalizeConnectionString(connectionString);
if (_config.GetConnectionString(SettingKeys.ConnectionStringKey) != connectionString)
{
- AddOrUpdateAppSetting($"{SettingKeys.ConnectionStringsSection}:{SettingKeys.ConnectionStringKey}", connectionString);
- _config.Reload();
+ _configManager.AddOrUpdateSetting($"{SettingKeys.ConnectionStringsSection}:{SettingKeys.ConnectionStringKey}", connectionString, true);
}
}
public void UpdateDatabaseType(string databaseType)
{
- AddOrUpdateAppSetting($"{SettingKeys.DatabaseSection}:{SettingKeys.DatabaseTypeKey}", databaseType);
- _config.Reload();
+ _configManager.AddOrUpdateSetting($"{SettingKeys.DatabaseSection}:{SettingKeys.DatabaseTypeKey}", databaseType, true);
}
public void UpgradeSqlServer(ISqlRepository sql, string connectionString, string databaseType, bool isMaster)
@@ -744,5 +703,24 @@ namespace Oqtane.Infrastructure
sql.ExecuteNonQuery(connectionString, databaseType, query);
}
+
+ private void ValidateConfiguration()
+ {
+ if (_configManager.GetSetting(SettingKeys.DatabaseSection, SettingKeys.DatabaseTypeKey, "") == "")
+ {
+ _configManager.AddOrUpdateSetting($"{SettingKeys.DatabaseSection}:{SettingKeys.DatabaseTypeKey}", Constants.DefaultDBType, true);
+ }
+ if (!_configManager.GetSection(SettingKeys.AvailableDatabasesSection).Exists())
+ {
+ string databases = "[";
+ databases += "{ \"Name\": \"LocalDB\", \"ControlType\": \"Oqtane.Installer.Controls.LocalDBConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.SqlServer.SqlServerDatabase, Oqtane.Database.SqlServer\" },";
+ databases += "{ \"Name\": \"SQL Server\", \"ControlType\": \"Oqtane.Installer.Controls.SqlServerConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.SqlServer.SqlServerDatabase, Oqtane.Database.SqlServer\" },";
+ databases += "{ \"Name\": \"SQLite\", \"ControlType\": \"Oqtane.Installer.Controls.SqliteConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.Sqlite.SqliteDatabase, Oqtane.Database.Sqlite\" },";
+ databases += "{ \"Name\": \"MySQL\", \"ControlType\": \"Oqtane.Installer.Controls.MySQLConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.MySQL.SqlServerDatabase, Oqtane.Database.MySQL\" },";
+ databases += "{ \"Name\": \"PostgreSQL\", \"ControlType\": \"Oqtane.Installer.Controls.PostgreSQLConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.PostgreSQL.PostgreSQLDatabase, Oqtane.Database.PostgreSQL\" }";
+ databases += "]";
+ _configManager.AddOrUpdateSetting(SettingKeys.AvailableDatabasesSection, JsonConvert.DeserializeObject(databases), true);
+ }
+ }
}
}
diff --git a/Oqtane.Server/Infrastructure/Interfaces/IConfigManager.cs b/Oqtane.Server/Infrastructure/Interfaces/IConfigManager.cs
new file mode 100644
index 00000000..cfc454b2
--- /dev/null
+++ b/Oqtane.Server/Infrastructure/Interfaces/IConfigManager.cs
@@ -0,0 +1,15 @@
+using Microsoft.Extensions.Configuration;
+
+namespace Oqtane.Infrastructure
+{
+ public interface IConfigManager
+ {
+ public IConfigurationSection GetSection(string sectionKey);
+ public string GetSetting(string sectionKey, string settingKey, string defaultValue);
+ void AddOrUpdateSetting(string key, T value, bool reload);
+ void AddOrUpdateSetting(string file, string key, T value, bool reload);
+ void RemoveSetting(string key, bool reload);
+ void RemoveSetting(string file, string key, bool reload);
+ void Reload();
+ }
+}
diff --git a/Oqtane.Server/Infrastructure/UpgradeManager.cs b/Oqtane.Server/Infrastructure/UpgradeManager.cs
index 184abd3d..dd806e3a 100644
--- a/Oqtane.Server/Infrastructure/UpgradeManager.cs
+++ b/Oqtane.Server/Infrastructure/UpgradeManager.cs
@@ -1,5 +1,7 @@
using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Newtonsoft.Json;
using Oqtane.Models;
using Oqtane.Repository;
using Oqtane.Shared;
@@ -11,15 +13,15 @@ namespace Oqtane.Infrastructure
{
public class UpgradeManager : IUpgradeManager
{
- private readonly IAliasRepository _aliases;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IWebHostEnvironment _environment;
+ private readonly IConfigManager _configManager;
- public UpgradeManager(IAliasRepository aliases, IServiceScopeFactory serviceScopeFactory, IWebHostEnvironment environment)
+ public UpgradeManager(IServiceScopeFactory serviceScopeFactory, IWebHostEnvironment environment, IConfigManager configManager)
{
- _aliases = aliases;
_serviceScopeFactory = serviceScopeFactory;
_environment = environment;
+ _configManager = configManager;
}
public void Upgrade(Tenant tenant, string version)
diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs
index 0a1dd1cd..061b78bc 100644
--- a/Oqtane.Server/Startup.cs
+++ b/Oqtane.Server/Startup.cs
@@ -58,7 +58,7 @@ namespace Oqtane
// Register localization services
services.AddLocalization(options => options.ResourcesPath = "Resources");
- services.AddOptions>().Bind(Configuration.GetSection("AvailableDatabases"));
+ services.AddOptions>().Bind(Configuration.GetSection(SettingKeys.AvailableDatabasesSection));
services.AddServerSideBlazor().AddCircuitOptions(options =>
{
@@ -176,6 +176,7 @@ namespace Oqtane
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
// install any modules or themes ( this needs to occur BEFORE the assemblies are loaded into the app domain )
InstallationManager.InstallPackages(_env.WebRootPath, _env.ContentRootPath);
diff --git a/Oqtane.Shared/Models/Database.cs b/Oqtane.Shared/Models/Database.cs
index ebce1d34..334aaddb 100644
--- a/Oqtane.Shared/Models/Database.cs
+++ b/Oqtane.Shared/Models/Database.cs
@@ -5,11 +5,6 @@ namespace Oqtane.Models
///
public class Database
{
- ///
- /// Friendly name for the Admin to identify the DB
- ///
- public string FriendlyName { get; set; }
-
///
/// Name of the Database
///
@@ -24,10 +19,5 @@ namespace Oqtane.Models
/// Type of DB using the full namespace, like `Oqtane.Database.SqlServer.SqlServerDatabase, Oqtane.Database.SqlServer`
///
public string DBType { get; set; }
-
- ///
- /// Software package responsible for using this DB - like `Oqtane.Database.MySQL`
- ///
- public string Package { get; set; }
}
}
diff --git a/Oqtane.Shared/Shared/InstallConfig.cs b/Oqtane.Shared/Shared/InstallConfig.cs
index 7848c522..358e6465 100644
--- a/Oqtane.Shared/Shared/InstallConfig.cs
+++ b/Oqtane.Shared/Shared/InstallConfig.cs
@@ -5,7 +5,6 @@ namespace Oqtane.Shared
{
public string ConnectionString { get; set; }
public string DatabaseType { get; set; }
- public string DatabasePackage { get; set; }
public string Aliases { get; set; }
public string TenantName { get; set; }
public bool IsNewTenant { get; set; }
diff --git a/Oqtane.Shared/Shared/SettingKeys.cs b/Oqtane.Shared/Shared/SettingKeys.cs
index 3aa66505..092a347c 100644
--- a/Oqtane.Shared/Shared/SettingKeys.cs
+++ b/Oqtane.Shared/Shared/SettingKeys.cs
@@ -16,5 +16,7 @@ namespace Oqtane.Shared
public const string DefaultThemeKey = "DefaultTheme";
public const string DefaultLayoutKey = "DefaultLayout";
public const string DefaultContainerKey = "DefaultContainer";
+
+ public const string AvailableDatabasesSection = "AvailableDatabases";
}
}