fix #2567 - migrate tenant connection string details from database to appsettings.json

This commit is contained in:
Shaun Walker
2023-02-23 16:29:15 -05:00
parent 71dd00da0f
commit f2df8e96db
33 changed files with 562 additions and 309 deletions

View File

@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@ -6,11 +7,13 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.Extensions.Configuration;
using Oqtane.Databases.Interfaces;
using Oqtane.Extensions;
using Oqtane.Infrastructure;
using Oqtane.Migrations.Framework;
using Oqtane.Models;
using Oqtane.Shared;
// ReSharper disable BuiltInTypeReferenceStyleForMemberAccess
@ -18,17 +21,17 @@ namespace Oqtane.Repository
{
public class DBContextBase : IdentityUserContext<IdentityUser>
{
private readonly ITenantResolver _tenantResolver;
private readonly ITenantManager _tenantManager;
private readonly IHttpContextAccessor _accessor;
private string _connectionString;
private string _databaseType;
private readonly IConfigurationRoot _config;
private string _connectionString = "";
private string _databaseType = "";
public DBContextBase(ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor)
public DBContextBase(IDBContextDependencies DBContextDependencies)
{
_connectionString = String.Empty;
_tenantManager = tenantManager;
_accessor = httpContextAccessor;
_tenantManager = DBContextDependencies.TenantManager;
_accessor = DBContextDependencies.Accessor;
_config = DBContextDependencies.Config;
}
public IDatabase ActiveDatabase { get; set; }
@ -39,21 +42,11 @@ namespace Oqtane.Repository
if (string.IsNullOrEmpty(_connectionString))
{
Tenant tenant;
if (_tenantResolver != null)
{
tenant = _tenantResolver.GetTenant();
}
else
{
tenant = _tenantManager.GetTenant();
}
Tenant tenant = _tenantManager.GetTenant();
if (tenant != null)
{
_connectionString = tenant.DBConnectionString
.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString());
_connectionString = _config.GetConnectionString(tenant.DBConnectionString)
.Replace($"|{Constants.DataDirectory}|", AppDomain.CurrentDomain.GetData(Constants.DataDirectory)?.ToString());
_databaseType = tenant.DBType;
}
}
@ -93,12 +86,17 @@ namespace Oqtane.Repository
return base.SaveChangesAsync(cancellationToken);
}
[Obsolete("This constructor is obsolete. Use DBContextBase(ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor) instead.", false)]
public DBContextBase(ITenantResolver tenantResolver, IHttpContextAccessor httpContextAccessor)
[Obsolete("This constructor is obsolete. Use DBContextBase(IDBContextDependencies DBContextDependencies) instead.", false)]
public DBContextBase(ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor)
{
_connectionString = String.Empty;
_tenantResolver = tenantResolver;
_tenantManager = tenantManager;
_accessor = httpContextAccessor;
// anti-pattern used to reference config service in base class without causing breaking change
_config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
}
}
}

View File

@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Oqtane.Infrastructure;
namespace Oqtane.Repository
{
public class DBContextDependencies : IDBContextDependencies
{
public DBContextDependencies(ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor, IConfigurationRoot config)
{
TenantManager = tenantManager;
Accessor = httpContextAccessor;
Config = config;
}
public ITenantManager TenantManager { get; }
public IHttpContextAccessor Accessor { get; }
public IConfigurationRoot Config { get; }
}
}

View File

@ -1,8 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Oqtane.Databases.Interfaces;
using Microsoft.EntityFrameworkCore;
using Oqtane.Extensions;
using Oqtane.Interfaces;
using Oqtane.Models;
using IDatabase = Oqtane.Databases.Interfaces.IDatabase;

View File

@ -41,8 +41,8 @@ namespace Oqtane.Repository
{
if (_config.IsInstalled())
{
_connectionString = _config.GetConnectionString("DefaultConnection")
.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString());
_connectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey)
.Replace($"|{Constants.DataDirectory}|", AppDomain.CurrentDomain.GetData(Constants.DataDirectory)?.ToString());
}
_databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey];

View File

@ -1,6 +1,4 @@
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Oqtane.Infrastructure;
using Oqtane.Models;
using Oqtane.Repository.Databases.Interfaces;
@ -12,7 +10,7 @@ namespace Oqtane.Repository
{
public class TenantDBContext : DBContextBase, IMultiDatabase
{
public TenantDBContext(ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor) : base(tenantManager, httpContextAccessor) { }
public TenantDBContext(IDBContextDependencies DBContextDependencies) : base(DBContextDependencies) { }
public virtual DbSet<Site> Site { get; set; }
public virtual DbSet<Page> Page { get; set; }

View File

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Oqtane.Infrastructure;
namespace Oqtane.Repository
{
public interface IDBContextDependencies
{
ITenantManager TenantManager { get; }
IHttpContextAccessor Accessor { get; }
IConfigurationRoot Config { get; }
}
}

View File

@ -1,4 +1,4 @@
using System.Data;
using System.Data;
using System.Reflection;
using Oqtane.Models;
@ -18,6 +18,8 @@ namespace Oqtane.Repository
IDataReader ExecuteReader(Tenant tenant, string query);
IDataReader ExecuteReader(string DBType, string DBConnectionString, string query);
string GetScriptFromAssembly(Assembly assembly, string fileName);
}
}

View File

@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Configuration;
using Oqtane.Databases.Interfaces;
using Oqtane.Interfaces;
using Oqtane.Models;
// ReSharper disable ConvertToUsingDeclaration
// ReSharper disable InvertIf
@ -15,6 +14,13 @@ namespace Oqtane.Repository
{
public class SqlRepository : ISqlRepository
{
private IConfigurationRoot _config;
public SqlRepository(IConfigurationRoot config)
{
_config = config;
}
public void ExecuteScript(Tenant tenant, string script)
{
// execute script in current tenant
@ -75,13 +81,19 @@ namespace Oqtane.Repository
public IDataReader ExecuteReader(Tenant tenant, string query)
{
var db = GetActiveDatabase(tenant.DBType);
return db.ExecuteReader(tenant.DBConnectionString, query);
return db.ExecuteReader(GetConnectionString(tenant.DBConnectionString), query);
}
public IDataReader ExecuteReader(string DBType, string DBConnectionString, string query)
{
var db = GetActiveDatabase(DBType);
return db.ExecuteReader(GetConnectionString(DBConnectionString), query);
}
public int ExecuteNonQuery(string connectionString, string databaseType, string query)
{
var db = GetActiveDatabase(databaseType);
return db.ExecuteNonQuery(connectionString, query);
return db.ExecuteNonQuery(GetConnectionString(connectionString), query);
}
public string GetScriptFromAssembly(Assembly assembly, string fileName)
@ -119,5 +131,14 @@ namespace Oqtane.Repository
return activeDatabase;
}
private string GetConnectionString(string connectionString)
{
if (!connectionString.Contains("="))
{
connectionString = _config.GetConnectionString(connectionString);
}
return connectionString;
}
}
}