added uninstall support for modules
This commit is contained in:
@ -26,10 +26,11 @@ namespace Oqtane.Controllers
|
||||
private readonly IInstallationManager _installationManager;
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
private readonly ITenantResolver _resolver;
|
||||
private readonly ITenantRepository _tenants;
|
||||
private readonly ISqlRepository _sql;
|
||||
private readonly ILogManager _logger;
|
||||
|
||||
public ModuleDefinitionController(IModuleDefinitionRepository moduleDefinitions, IModuleRepository modules, IUserPermissions userPermissions, IInstallationManager installationManager, IWebHostEnvironment environment, ITenantResolver resolver, ISqlRepository sql, ILogManager logger)
|
||||
public ModuleDefinitionController(IModuleDefinitionRepository moduleDefinitions, IModuleRepository modules, IUserPermissions userPermissions, IInstallationManager installationManager, IWebHostEnvironment environment, ITenantResolver resolver, ITenantRepository tenants, ISqlRepository sql, ILogManager logger)
|
||||
{
|
||||
_moduleDefinitions = moduleDefinitions;
|
||||
_modules = modules;
|
||||
@ -37,6 +38,7 @@ namespace Oqtane.Controllers
|
||||
_installationManager = installationManager;
|
||||
_environment = environment;
|
||||
_resolver = resolver;
|
||||
_tenants = tenants;
|
||||
_sql = sql;
|
||||
_logger = logger;
|
||||
}
|
||||
@ -102,23 +104,59 @@ namespace Oqtane.Controllers
|
||||
ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionId == id).FirstOrDefault();
|
||||
if (moduledefinition != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(moduledefinition.ServerAssemblyName))
|
||||
{
|
||||
string uninstallScript = "";
|
||||
Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(a => a.GetName().Name == moduledefinition.ServerAssemblyName);
|
||||
if (assembly != null)
|
||||
{
|
||||
Stream resourceStream = assembly.GetManifestResourceStream(moduledefinition.ServerAssemblyName + ".Scripts.Uninstall.sql");
|
||||
if (resourceStream != null)
|
||||
{
|
||||
using (var reader = new StreamReader(resourceStream))
|
||||
{
|
||||
uninstallScript = reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Tenant tenant in _tenants.GetTenants())
|
||||
{
|
||||
// uninstall module database schema
|
||||
if (!string.IsNullOrEmpty(uninstallScript))
|
||||
{
|
||||
_sql.ExecuteScript(tenant, uninstallScript);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Uninstall Script Executed For {ServerAssemblyName}", moduledefinition.ServerAssemblyName);
|
||||
}
|
||||
// clean up module schema versions
|
||||
_sql.ExecuteNonQuery(tenant, "DELETE FROM [dbo].[SchemaVersions] WHERE ScriptName LIKE '" + moduledefinition.ServerAssemblyName + "%'");
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Schema Versions Removed For {ServerAssemblyName}", moduledefinition.ServerAssemblyName);
|
||||
}
|
||||
}
|
||||
|
||||
string moduledefinitionname = moduledefinition.ModuleDefinitionName.Substring(0, moduledefinition.ModuleDefinitionName.IndexOf(","));
|
||||
|
||||
// clean up module static resource folder
|
||||
string folder = Path.Combine(_environment.WebRootPath, "Modules\\" + moduledefinitionname);
|
||||
if (Directory.Exists(folder))
|
||||
{
|
||||
Directory.Delete(folder, true);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Static Resources Removed For {ModuleDefinitionName}", moduledefinitionname);
|
||||
}
|
||||
|
||||
// remove module assembly from /bin
|
||||
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
foreach (string file in Directory.EnumerateFiles(binfolder, moduledefinitionname + "*.dll"))
|
||||
foreach (string file in Directory.EnumerateFiles(binfolder, moduledefinitionname + "*.*"))
|
||||
{
|
||||
System.IO.File.Delete(file);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assemblies Removed For {ModuleDefinitionName}", moduledefinitionname);
|
||||
}
|
||||
|
||||
// remove module definition
|
||||
_moduleDefinitions.DeleteModuleDefinition(id, siteid);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Deleted {ModuleDefinitionId}", id);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition Deleted {ModuleDefinitionName}", moduledefinition.Name);
|
||||
|
||||
// restart application
|
||||
_installationManager.RestartApplication();
|
||||
}
|
||||
}
|
||||
@ -209,10 +247,7 @@ namespace Oqtane.Controllers
|
||||
if (Path.GetExtension(filePath) == ".sql")
|
||||
{
|
||||
// execute script in curent tenant
|
||||
foreach (string query in text.Split("GO", StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
_sql.ExecuteNonQuery(_resolver.GetTenant(), query);
|
||||
}
|
||||
_sql.ExecuteScript(_resolver.GetTenant(), text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
using Oqtane.Controllers;
|
||||
using Oqtane.Extensions;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Repository;
|
||||
@ -109,7 +108,7 @@ namespace Oqtane.Infrastructure
|
||||
}
|
||||
else
|
||||
{
|
||||
Message = "Database is not avaiable";
|
||||
Message = "Database is not available";
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -214,7 +213,7 @@ namespace Oqtane.Infrastructure
|
||||
|
||||
Console.WriteLine($"Migrating assembly {assembly.FullName}");
|
||||
var dbUpgradeConfig = DeployChanges.To.SqlDatabase(connectionString)
|
||||
.WithScriptsEmbeddedInAssembly(assembly); // scripts must be included as Embedded Resources
|
||||
.WithScriptsEmbeddedInAssembly(assembly, s => !s.ToLower().Contains("uninstall.sql")); // scripts must be included as Embedded Resources
|
||||
var dbUpgrade = dbUpgradeConfig.Build();
|
||||
if (dbUpgrade.IsUpgradeRequired())
|
||||
{
|
||||
@ -368,8 +367,6 @@ namespace Oqtane.Infrastructure
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void CreateHostUser(IFolderRepository folderRepository, IUserRoleRepository userRoleRepository, IRoleRepository roleRepository, IUserRepository userRepository, UserManager<IdentityUser> identityUserManager, User user)
|
||||
{
|
||||
var identityUser = new IdentityUser {UserName = user.Username, Email = user.Email, EmailConfirmed = true};
|
||||
@ -427,7 +424,6 @@ namespace Oqtane.Infrastructure
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool TableExists(DbContext context, string tableName)
|
||||
{
|
||||
return TableExists(context, "dbo", tableName);
|
||||
|
@ -5,6 +5,7 @@ namespace Oqtane.Repository
|
||||
{
|
||||
public interface ISqlRepository
|
||||
{
|
||||
void ExecuteScript(Tenant tenant, string script);
|
||||
int ExecuteNonQuery(Tenant tenant, string query);
|
||||
SqlDataReader ExecuteReader(Tenant tenant, string query);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ namespace Oqtane.Repository
|
||||
private MasterDBContext _db;
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly IPermissionRepository _permissions;
|
||||
private List<ModuleDefinition> _moduleDefinitions; // lazy load
|
||||
|
||||
public ModuleDefinitionRepository(MasterDBContext context, IMemoryCache cache, IPermissionRepository permissions)
|
||||
{
|
||||
@ -61,12 +62,12 @@ namespace Oqtane.Repository
|
||||
|
||||
private List<ModuleDefinition> LoadSiteModuleDefinitions(int siteId)
|
||||
{
|
||||
// get module assemblies
|
||||
List<ModuleDefinition> moduleDefinitions = _cache.GetOrCreate("moduledefinitions", entry =>
|
||||
if (_moduleDefinitions == null)
|
||||
{
|
||||
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||
return LoadModuleDefinitionsFromAssemblies();
|
||||
});
|
||||
// get module assemblies
|
||||
_moduleDefinitions = LoadModuleDefinitionsFromAssemblies();
|
||||
}
|
||||
List<ModuleDefinition> moduleDefinitions = _moduleDefinitions;
|
||||
|
||||
// get module definition permissions for site
|
||||
List<Permission> permissions = _permissions.GetPermissions(siteId, EntityNames.ModuleDefinition).ToList();
|
||||
@ -210,14 +211,5 @@ namespace Oqtane.Repository
|
||||
return moduledefinitions;
|
||||
}
|
||||
|
||||
private string GetProperty(Dictionary<string, string> properties, string key)
|
||||
{
|
||||
string value = "";
|
||||
if (properties.ContainsKey(key))
|
||||
{
|
||||
value = properties[key];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,15 @@ namespace Oqtane.Repository
|
||||
public class SqlRepository : ISqlRepository
|
||||
{
|
||||
|
||||
public void ExecuteScript(Tenant tenant, string script)
|
||||
{
|
||||
// execute script in curent tenant
|
||||
foreach (string query in script.Split("GO", StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
ExecuteNonQuery(tenant, query);
|
||||
}
|
||||
}
|
||||
|
||||
public int ExecuteNonQuery(Tenant tenant, string query)
|
||||
{
|
||||
SqlConnection conn = new SqlConnection(FormatConnectionString(tenant.DBConnectionString));
|
||||
|
@ -9,7 +9,24 @@ namespace Oqtane.Repository
|
||||
{
|
||||
public class ThemeRepository : IThemeRepository
|
||||
{
|
||||
private List<Theme> _themes; // lazy load
|
||||
|
||||
public IEnumerable<Theme> GetThemes()
|
||||
{
|
||||
return LoadThemes();
|
||||
}
|
||||
|
||||
private List<Theme> LoadThemes()
|
||||
{
|
||||
if (_themes == null)
|
||||
{
|
||||
// get themes
|
||||
_themes = LoadThemesFromAssemblies();
|
||||
}
|
||||
return _themes;
|
||||
}
|
||||
|
||||
private List<Theme> LoadThemesFromAssemblies()
|
||||
{
|
||||
List<Theme> themes = new List<Theme>();
|
||||
|
||||
@ -103,20 +120,5 @@ namespace Oqtane.Repository
|
||||
}
|
||||
return themes;
|
||||
}
|
||||
|
||||
private string GetProperty(Dictionary<string, string> properties, string key)
|
||||
{
|
||||
string value = "";
|
||||
if (properties.ContainsKey(key))
|
||||
{
|
||||
value = properties[key];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public IEnumerable<Theme> GetThemes()
|
||||
{
|
||||
return LoadThemes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user