DI: dbManager

This commit is contained in:
pavelbannov 2019-10-21 15:33:02 +03:00
parent 247a3b787f
commit e82366a2cd
32 changed files with 771 additions and 701 deletions

View File

@ -29,10 +29,12 @@ using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Threading.Tasks;
using ASC.Common.Data.AdoProxy;
using ASC.Common.Data.Sql;
using ASC.Common.Logging;
using ASC.Common.Web;
using Microsoft.Extensions.Options;
namespace ASC.Common.Data
@ -67,16 +69,20 @@ namespace ASC.Common.Data
public class ConfigureDbManager : IConfigureNamedOptions<DbManager>
{
public DbRegistry DbRegistry { get; }
public IOptionsMonitor<LogNLog> Option { get; }
public ConfigureDbManager(DbRegistry dbRegistry)
public ConfigureDbManager(DbRegistry dbRegistry, IOptionsMonitor<LogNLog> option)
{
DbRegistry = dbRegistry;
Option = option;
}
public void Configure(string name, DbManager dbManager)
{
dbManager.DbRegistry = DbRegistry;
dbManager.DatabaseId = string.IsNullOrEmpty(name) ? "default" : name;
dbManager.Logger = Option.Get("ASC.SQL");
}
public void Configure(DbManager dbManager)
@ -88,7 +94,7 @@ namespace ASC.Common.Data
public class DbManager : IDbManager
{
private readonly ILog logger = LogManager.GetLogger("ASC.SQL");
public ILog Logger { get; internal set; }
private readonly ProxyContext proxyContext;
private readonly bool shared;
@ -155,7 +161,7 @@ namespace ASC.Common.Data
DatabaseId = databaseId ?? throw new ArgumentNullException(nameof(databaseId));
this.shared = shared;
if (logger.IsDebugEnabled)
if (Logger.IsDebugEnabled)
{
proxyContext = new ProxyContext(AdoProxyExecutedEventHandler);
}
@ -185,22 +191,6 @@ namespace ASC.Common.Data
#endregion
public static IDbManager FromHttpContext(DbRegistry dbRegistry, string databaseId)
{
if (HttpContext.Current != null)
{
if (!(DisposableHttpContext.Current[databaseId] is DbManager dbManager) || dbManager.disposed)
{
var localDbManager = new DbManager(dbRegistry, databaseId);
var dbManagerAdapter = new DbManagerProxy(localDbManager);
DisposableHttpContext.Current[databaseId] = localDbManager;
return dbManagerAdapter;
}
return new DbManagerProxy(dbManager);
}
return new DbManager(dbRegistry, databaseId);
}
private DbConnection OpenConnection()
{
var connection = GetConnection();
@ -367,7 +357,7 @@ namespace ASC.Common.Data
private void AdoProxyExecutedEventHandler(ExecutedEventArgs a)
{
logger.DebugWithProps(a.SqlMethod,
Logger.DebugWithProps(a.SqlMethod,
new KeyValuePair<string, object>("duration", a.Duration.TotalMilliseconds),
new KeyValuePair<string, object>("sql", RemoveWhiteSpaces(a.Sql)),
new KeyValuePair<string, object>("sqlParams", RemoveWhiteSpaces(a.SqlParameters))
@ -380,6 +370,11 @@ namespace ASC.Common.Data
str.Replace(Environment.NewLine, " ").Replace("\n", "").Replace("\r", "").Replace("\t", " ") :
string.Empty;
}
public ISqlDialect GetSqlDialect(string databaseId)
{
return DbRegistry.GetSqlDialect(databaseId);
}
}
public class DbManagerProxy : IDbManager
@ -467,5 +462,10 @@ namespace ASC.Common.Data
{
return dbManager.ExecuteBatch(batch);
}
public ISqlDialect GetSqlDialect(string databaseId)
{
return dbManager.GetSqlDialect(databaseId);
}
}
}

View File

@ -38,6 +38,7 @@ namespace ASC.Common.Data
DbConnection Connection { get; }
string DatabaseId { get; }
bool InTransaction { get; }
ISqlDialect GetSqlDialect(string databaseId);
IDbTransaction BeginTransaction();

View File

@ -54,17 +54,14 @@ namespace ASC.Common.Data
}
public MultiRegionalDbManager(IConfiguration configuration, DbRegistry dbRegistry, string dbId)
public MultiRegionalDbManager(IConfiguration configuration, DbOptionsManager optionsManager, string dbId)
{
const StringComparison cmp = StringComparison.InvariantCultureIgnoreCase;
DatabaseId = dbId;
databases = configuration.GetConnectionStrings()
.Where(c => c.Name.Equals(dbId, cmp) || c.Name.StartsWith(dbId + ".", cmp))
.Select(
c =>
HttpContext.Current != null
? DbManager.FromHttpContext(dbRegistry, c.Name)
: new DbManager(dbRegistry, c.Name))
.Select(c => optionsManager.Get(c.Name))
.Cast<IDbManager>()
.ToList();
localDb = databases.SingleOrDefault(db => db.DatabaseId.Equals(dbId, cmp));
}
@ -85,11 +82,6 @@ namespace ASC.Common.Data
}
}
public static MultiRegionalDbManager FromHttpContext(IConfiguration configuration, DbRegistry dbRegistry, string databaseId)
{
return new MultiRegionalDbManager(configuration, dbRegistry, databaseId);
}
public IDbTransaction BeginTransaction(IsolationLevel isolationLevel)
{
return localDb.BeginTransaction(isolationLevel);
@ -180,5 +172,10 @@ namespace ASC.Common.Data
{
return localDb.BeginTransaction();
}
public ISqlDialect GetSqlDialect(string databaseId)
{
return localDb.GetSqlDialect(databaseId);
}
}
}

View File

@ -38,13 +38,13 @@ namespace ASC.Geolocation
{
private readonly string dbid;
public DbRegistry DbRegistry { get; }
public ILog Log { get; }
public DbOptionsManager DbOptions { get; }
public GeolocationHelper(DbRegistry dbRegistry, IOptionsMonitor<LogNLog> option, string dbid)
public GeolocationHelper(DbOptionsManager dbOptions, IOptionsMonitor<LogNLog> option, string dbid)
{
Log = option.CurrentValue;
DbRegistry = dbRegistry;
DbOptions = dbOptions;
this.dbid = dbid;
}
@ -54,7 +54,7 @@ namespace ASC.Geolocation
try
{
var ipformatted = FormatIP(ip);
using var db = new DbManager(DbRegistry, dbid);
var db = DbOptions.Get(dbid);
var q = new SqlQuery("dbip_location")
.Select("ip_start", "ip_end", "country", "city", "timezone_offset", "timezone_name")
.Where(Exp.Le("ip_start", ipformatted))

View File

@ -102,16 +102,15 @@ namespace ASC.Core.Billing
public TariffServiceStorage TariffServiceStorage { get; }
public TariffService(
System.Configuration.ConnectionStringSettings connectionString,
IQuotaService quotaService,
ITenantService tenantService,
CoreBaseSettings coreBaseSettings,
CoreSettings coreSettings,
IConfiguration configuration,
DbRegistry dbRegistry,
DbOptionsManager dbOptionsManager,
TariffServiceStorage tariffServiceStorage,
IOptionsMonitor<LogNLog> options)
: base(connectionString, dbRegistry, "tenant")
: base(dbOptionsManager, "tenant")
{
log = options.CurrentValue;
this.quotaService = quotaService;
@ -412,7 +411,7 @@ client.GetPaymentUrls(null, products, !string.IsNullOrEmpty(affiliateId) ? affil
var inserted = false;
if (!Equals(bi, GetBillingInfo(tenant)))
{
using var db = GetDb();
var db = GetDb();
using var tx = db.BeginTransaction();
// last record is not the same
var q = new SqlQuery("tenants_tariff").SelectCount().Where("tenant", tenant).Where("tariff", bi.Item1).Where("stamp", bi.Item2);
@ -444,7 +443,7 @@ client.GetPaymentUrls(null, products, !string.IsNullOrEmpty(affiliateId) ? affil
public void DeleteDefaultBillingInfo()
{
const int tenant = Tenant.DEFAULT_TENANT;
using (var db = GetDb())
var db = GetDb();
{
db.ExecuteNonQuery(new SqlUpdate("tenants_tariff")
.Set("tenant", -2)

View File

@ -48,13 +48,16 @@ namespace ASC.Core.Billing
private Timer timer;
public TariffSyncService(IServiceProvider serviceProvider, IConfiguration configuration, DbRegistry dbRegistry,
public TariffSyncService(
IServiceProvider serviceProvider,
IConfiguration configuration,
DbQuotaService dbQuotaService,
IOptionsMonitor<LogNLog> options)
{
config = TariffSyncServiceSection.GetSection();
ServiceProvider = serviceProvider;
Configuration = configuration;
DbRegistry = dbRegistry;
DbQuotaService = dbQuotaService;
log = options.CurrentValue;
}
@ -68,7 +71,7 @@ namespace ASC.Core.Billing
{
var cs = Configuration.GetConnectionStrings(config.ConnectionStringName + version) ??
Configuration.GetConnectionStrings(config.ConnectionStringName);
quotaServices[version] = new DbQuotaService(cs, DbRegistry).GetTenantQuotas();
quotaServices[version] = DbQuotaService.GetTenantQuotas();
}
return quotaServices[version];
}
@ -83,7 +86,7 @@ namespace ASC.Core.Billing
public IServiceProvider ServiceProvider { get; }
public IConfiguration Configuration { get; }
public DbRegistry DbRegistry { get; }
public DbQuotaService DbQuotaService { get; }
public void Start()
{
@ -109,7 +112,7 @@ namespace ASC.Core.Billing
{
var scope = ServiceProvider.CreateScope();
var tariffSync = scope.ServiceProvider.GetService<TariffSync>();
tariffSync.Sync(config, Configuration);
tariffSync.Sync();
}
catch (Exception error)
@ -121,24 +124,26 @@ namespace ASC.Core.Billing
class TariffSync
{
public TariffSync(TenantManager tenantManager, DbRegistry dbRegistry, CoreSettings coreSettings)
public TariffSync(TenantManager tenantManager, DbRegistry dbRegistry, CoreSettings coreSettings, DbQuotaService dbQuotaService)
{
TenantManager = tenantManager;
DbRegistry = dbRegistry;
CoreSettings = coreSettings;
DbQuotaService = dbQuotaService;
}
public TenantManager TenantManager { get; }
public DbRegistry DbRegistry { get; }
public CoreSettings CoreSettings { get; }
public DbQuotaService DbQuotaService { get; }
public void Sync(TariffSyncServiceSection config, IConfiguration configuration)
public void Sync()
{
var tenant = TenantManager.GetTenants(false).OrderByDescending(t => t.Version).FirstOrDefault();
if (tenant != null)
{
using var wcfClient = new TariffSyncClient();
var quotaService = new DbQuotaService(configuration.GetConnectionStrings(config.ConnectionStringName), DbRegistry);
var quotaService = DbQuotaService;
var oldtariffs = quotaService.GetTenantQuotas().ToDictionary(t => t.Id);
// save new

View File

@ -27,38 +27,77 @@
using System;
using System.Collections.Generic;
using ASC.Common.Caching;
using ASC.Core.Data;
namespace ASC.Core.Caching
{
public class CachedAzService : IAzService
public class AzServiceCache
{
private readonly IAzService service;
private readonly ICache cache;
private readonly ICacheNotify<AzRecordCache> cacheNotify;
public ICache Cache { get; }
public ICacheNotify<AzRecordCache> CacheNotify { get; }
public TimeSpan CacheExpiration { get; set; }
public CachedAzService(IAzService service, ICacheNotify<AzRecordCache> cacheNotify)
public AzServiceCache(ICacheNotify<AzRecordCache> cacheNotify)
{
this.service = service ?? throw new ArgumentNullException("service");
cache = AscCache.Memory;
CacheExpiration = TimeSpan.FromMinutes(10);
CacheNotify = cacheNotify;
Cache = AscCache.Memory;
cacheNotify.Subscribe((r) => UpdateCache(r, true), CacheNotifyAction.Remove);
cacheNotify.Subscribe((r) => UpdateCache(r, false), CacheNotifyAction.InsertOrUpdate);
}
private void UpdateCache(AzRecord r, bool remove)
{
var aces = Cache.Get<AzRecordStore>(GetKey(r.Tenant));
if (aces != null)
{
lock (aces)
{
if (remove)
{
aces.Remove(r);
}
else
{
aces.Add(r);
}
}
}
}
public static string GetKey(int tenant)
{
return "acl" + tenant.ToString();
}
}
public class CachedAzService : IAzService
{
private readonly IAzService service;
private readonly ICacheNotify<AzRecordCache> cacheNotify;
public ICache Cache { get; }
public TimeSpan CacheExpiration { get; set; }
public CachedAzService(DbAzService service, AzServiceCache azServiceCache)
{
this.service = service ?? throw new ArgumentNullException("service");
Cache = azServiceCache.Cache;
cacheNotify = azServiceCache.CacheNotify;
CacheExpiration = TimeSpan.FromMinutes(10);
}
public IEnumerable<AzRecord> GetAces(int tenant, DateTime from)
{
var key = GetKey(tenant);
var aces = cache.Get<AzRecordStore>(key);
var key = AzServiceCache.GetKey(tenant);
var aces = Cache.Get<AzRecordStore>(key);
if (aces == null)
{
var records = service.GetAces(tenant, default);
cache.Insert(key, aces = new AzRecordStore(records), DateTime.UtcNow.Add(CacheExpiration));
Cache.Insert(key, aces = new AzRecordStore(records), DateTime.UtcNow.Add(CacheExpiration));
}
return aces;
}
@ -75,30 +114,5 @@ namespace ASC.Core.Caching
service.RemoveAce(tenant, r);
cacheNotify.Publish(r, CacheNotifyAction.Remove);
}
private string GetKey(int tenant)
{
return "acl" + tenant.ToString();
}
private void UpdateCache(AzRecord r, bool remove)
{
var aces = cache.Get<AzRecordStore>(GetKey(r.Tenant));
if (aces != null)
{
lock (aces)
{
if (remove)
{
aces.Remove(r);
}
else
{
aces.Add(r);
}
}
}
}
}
}

View File

@ -28,54 +28,83 @@ using System;
using System.Collections.Generic;
using System.Linq;
using ASC.Common.Caching;
using ASC.Core.Data;
using ASC.Core.Tenants;
using Microsoft.Extensions.Configuration;
namespace ASC.Core.Caching
{
public class CachedQuotaService : IQuotaService
public class QuotaServiceCache
{
private const string KEY_QUOTA = "quota";
private const string KEY_QUOTA_ROWS = "quotarows";
private readonly IQuotaService service;
private readonly ICache cache;
private readonly ICacheNotify<QuotaCacheItem> cacheNotify;
private readonly TrustInterval interval;
internal const string KEY_QUOTA = "quota";
internal const string KEY_QUOTA_ROWS = "quotarows";
public TrustInterval Interval { get; set; }
public ICache Cache { get; }
public ICacheNotify<QuotaCacheItem> CacheNotify { get; }
public TimeSpan CacheExpiration
public bool QuotaCacheEnabled { get; }
public QuotaServiceCache(IConfiguration Configuration, ICacheNotify<QuotaCacheItem> cacheNotify)
{
get;
set;
}
if (Configuration["core:enable-quota-cache"] == null)
{
QuotaCacheEnabled = true;
}
else
{
QuotaCacheEnabled = !bool.TryParse(Configuration["core:enable-quota-cache"], out var enabled) || enabled;
}
public CachedQuotaService(IQuotaService service, ICacheNotify<QuotaCacheItem> cacheNotify)
{
this.service = service ?? throw new ArgumentNullException("service");
cache = AscCache.Memory;
interval = new TrustInterval();
CacheExpiration = TimeSpan.FromMinutes(10);
CacheNotify = cacheNotify;
Cache = AscCache.Memory;
Interval = new TrustInterval();
cacheNotify.Subscribe((i) =>
{
if (i.Key == KEY_QUOTA_ROWS)
{
interval.Expire();
Interval.Expire();
}
else if (i.Key == KEY_QUOTA)
{
cache.Remove(KEY_QUOTA);
Cache.Remove(KEY_QUOTA);
}
}, CacheNotifyAction.Any);
}
}
public class CachedQuotaService : IQuotaService
{
private readonly IQuotaService service;
private readonly ICache cache;
private readonly ICacheNotify<QuotaCacheItem> cacheNotify;
private readonly TrustInterval interval;
public TimeSpan CacheExpiration { get; set; }
public QuotaServiceCache QuotaServiceCache { get; }
public CachedQuotaService(DbQuotaService service, QuotaServiceCache quotaServiceCache)
{
this.service = service ?? throw new ArgumentNullException("service");
QuotaServiceCache = quotaServiceCache;
cache = quotaServiceCache.Cache;
interval = new TrustInterval();
CacheExpiration = TimeSpan.FromMinutes(10);
cacheNotify = quotaServiceCache.CacheNotify;
}
public IEnumerable<TenantQuota> GetTenantQuotas()
{
var quotas = cache.Get<IEnumerable<TenantQuota>>(KEY_QUOTA);
var quotas = cache.Get<IEnumerable<TenantQuota>>(QuotaServiceCache.KEY_QUOTA);
if (quotas == null)
{
cache.Insert(KEY_QUOTA, quotas = service.GetTenantQuotas(), DateTime.UtcNow.Add(CacheExpiration));
quotas = service.GetTenantQuotas();
if (QuotaServiceCache.QuotaCacheEnabled)
{
cache.Insert(QuotaServiceCache.KEY_QUOTA, quotas, DateTime.UtcNow.Add(CacheExpiration));
}
}
return quotas;
}
@ -88,7 +117,7 @@ namespace ASC.Core.Caching
public TenantQuota SaveTenantQuota(TenantQuota quota)
{
var q = service.SaveTenantQuota(quota);
cacheNotify.Publish(new QuotaCacheItem { Key = KEY_QUOTA }, CacheNotifyAction.Any);
cacheNotify.Publish(new QuotaCacheItem { Key = QuotaServiceCache.KEY_QUOTA }, CacheNotifyAction.Any);
return q;
}
@ -101,14 +130,14 @@ namespace ASC.Core.Caching
public void SetTenantQuotaRow(TenantQuotaRow row, bool exchange)
{
service.SetTenantQuotaRow(row, exchange);
cacheNotify.Publish(new QuotaCacheItem { Key = KEY_QUOTA_ROWS }, CacheNotifyAction.Any);
cacheNotify.Publish(new QuotaCacheItem { Key = QuotaServiceCache.KEY_QUOTA_ROWS }, CacheNotifyAction.Any);
}
public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(TenantQuotaRowQuery query)
{
if (query == null) throw new ArgumentNullException("query");
var rows = cache.Get<Dictionary<string, List<TenantQuotaRow>>>(KEY_QUOTA_ROWS);
var rows = cache.Get<Dictionary<string, List<TenantQuotaRow>>>(QuotaServiceCache.KEY_QUOTA_ROWS);
if (rows == null || interval.Expired)
{
var date = rows != null ? interval.StartTime : DateTime.MinValue;
@ -146,10 +175,13 @@ namespace ASC.Core.Caching
}
}
cache.Insert(KEY_QUOTA_ROWS, rows, DateTime.UtcNow.Add(CacheExpiration));
if (QuotaServiceCache.QuotaCacheEnabled)
{
cache.Insert(QuotaServiceCache.KEY_QUOTA_ROWS, rows, DateTime.UtcNow.Add(CacheExpiration));
}
}
var quotaRows = cache.Get<Dictionary<string, List<TenantQuotaRow>>>(KEY_QUOTA_ROWS);
var quotaRows = cache.Get<Dictionary<string, List<TenantQuotaRow>>>(QuotaServiceCache.KEY_QUOTA_ROWS);
if (quotaRows == null)
{
return Enumerable.Empty<TenantQuotaRow>();

View File

@ -28,9 +28,77 @@ using System;
using System.Collections.Generic;
using System.Linq;
using ASC.Common.Caching;
using ASC.Core.Data;
namespace ASC.Core.Caching
{
public class SubscriptionServiceCache
{
public ICache Cache { get; }
public ICacheNotify<SubscriptionRecord> NotifyRecord { get; }
public ICacheNotify<SubscriptionMethodCache> NotifyMethod { get; }
public SubscriptionServiceCache(ICacheNotify<SubscriptionRecord> notifyRecord, ICacheNotify<SubscriptionMethodCache> notifyMethod)
{
Cache = AscCache.Memory;
NotifyRecord = notifyRecord;
NotifyMethod = notifyMethod;
notifyRecord.Subscribe((s) =>
{
var store = GetSubsciptionsStore(s.Tenant, s.SourceId, s.ActionId);
if (store != null)
{
lock (store)
{
store.SaveSubscription(s);
}
}
}, CacheNotifyAction.InsertOrUpdate);
notifyRecord.Subscribe((s) =>
{
var store = GetSubsciptionsStore(s.Tenant, s.SourceId, s.ActionId);
if (store != null)
{
lock (store)
{
if (s.ObjectId == null)
{
store.RemoveSubscriptions();
}
else
{
store.RemoveSubscriptions(s.ObjectId);
}
}
}
}, CacheNotifyAction.Remove);
notifyMethod.Subscribe((m) =>
{
var store = GetSubsciptionsStore(m.Tenant, m.SourceId, m.ActionId);
if (store != null)
{
lock (store)
{
store.SetSubscriptionMethod(m);
}
}
}, CacheNotifyAction.Any);
}
private SubsciptionsStore GetSubsciptionsStore(int tenant, string sourceId, string actionId)
{
return Cache.Get<SubsciptionsStore>(GetKey(tenant, sourceId, actionId));
}
public static string GetKey(int tenant, string sourceId, string actionId)
{
return string.Format("sub/{0}/{1}/{2}", tenant, sourceId, actionId);
}
}
public class CachedSubscriptionService : ISubscriptionService
{
private readonly ISubscriptionService service;
@ -40,46 +108,13 @@ namespace ASC.Core.Caching
public TimeSpan CacheExpiration { get; set; }
public CachedSubscriptionService(ISubscriptionService service, ICacheNotify<SubscriptionRecord> notifyRecord, ICacheNotify<SubscriptionMethodCache> notifyMethod)
public CachedSubscriptionService(DbSubscriptionService service, SubscriptionServiceCache subscriptionServiceCache)
{
this.service = service ?? throw new ArgumentNullException("service");
cache = AscCache.Memory;
cache = subscriptionServiceCache.Cache;
notifyRecord = subscriptionServiceCache.NotifyRecord;
notifyMethod = subscriptionServiceCache.NotifyMethod;
CacheExpiration = TimeSpan.FromMinutes(5);
notifyRecord.Subscribe((s) =>
{
var store = GetSubsciptionsStore(s.Tenant, s.SourceId, s.ActionId);
lock (store)
{
store.SaveSubscription(s);
}
}, CacheNotifyAction.InsertOrUpdate);
notifyRecord.Subscribe((s) =>
{
var store = GetSubsciptionsStore(s.Tenant, s.SourceId, s.ActionId);
lock (store)
{
if (s.ObjectId == null)
{
store.RemoveSubscriptions();
}
else
{
store.RemoveSubscriptions(s.ObjectId);
}
}
}, CacheNotifyAction.Remove);
notifyMethod.Subscribe((m) =>
{
var store = GetSubsciptionsStore(m.Tenant, m.SourceId, m.ActionId);
lock (store)
{
store.SetSubscriptionMethod(m);
}
}, CacheNotifyAction.Any);
}
@ -146,7 +181,7 @@ namespace ASC.Core.Caching
private SubsciptionsStore GetSubsciptionsStore(int tenant, string sourceId, string actionId)
{
var key = string.Format("sub/{0}/{1}/{2}", tenant, sourceId, actionId);
var key = SubscriptionServiceCache.GetKey(tenant, sourceId, actionId);
var store = cache.Get<SubsciptionsStore>(key);
if (store == null)
{
@ -156,97 +191,95 @@ namespace ASC.Core.Caching
}
return store;
}
}
internal class SubsciptionsStore
{
private readonly List<SubscriptionRecord> records;
private IDictionary<string, List<SubscriptionRecord>> recordsByRec;
private IDictionary<string, List<SubscriptionRecord>> recordsByObj;
private readonly List<SubscriptionMethod> methods;
private IDictionary<string, List<SubscriptionMethod>> methodsByRec;
private class SubsciptionsStore
public SubsciptionsStore(IEnumerable<SubscriptionRecord> records, IEnumerable<SubscriptionMethod> methods)
{
private readonly List<SubscriptionRecord> records;
private IDictionary<string, List<SubscriptionRecord>> recordsByRec;
private IDictionary<string, List<SubscriptionRecord>> recordsByObj;
this.records = records.ToList();
this.methods = methods.ToList();
BuildSubscriptionsIndex(records);
BuildMethodsIndex(methods);
}
private readonly List<SubscriptionMethod> methods;
private IDictionary<string, List<SubscriptionMethod>> methodsByRec;
public IEnumerable<SubscriptionRecord> GetSubscriptions()
{
return records.ToList();
}
public SubsciptionsStore(IEnumerable<SubscriptionRecord> records, IEnumerable<SubscriptionMethod> methods)
public IEnumerable<SubscriptionRecord> GetSubscriptions(string recipientId, string objectId)
{
return recipientId != null ?
recordsByRec.ContainsKey(recipientId) ? recordsByRec[recipientId].ToList() : new List<SubscriptionRecord>() :
recordsByObj.ContainsKey(objectId ?? string.Empty) ? recordsByObj[objectId ?? string.Empty].ToList() : new List<SubscriptionRecord>();
}
public SubscriptionRecord GetSubscription(string recipientId, string objectId)
{
return recordsByRec.ContainsKey(recipientId) ?
recordsByRec[recipientId].Where(s => s.ObjectId == objectId).FirstOrDefault() :
null;
}
public void SaveSubscription(SubscriptionRecord s)
{
var old = GetSubscription(s.RecipientId, s.ObjectId);
if (old != null)
{
this.records = records.ToList();
this.methods = methods.ToList();
BuildSubscriptionsIndex(records);
BuildMethodsIndex(methods);
old.Subscribed = s.Subscribed;
}
public IEnumerable<SubscriptionRecord> GetSubscriptions()
else
{
return records.ToList();
}
public IEnumerable<SubscriptionRecord> GetSubscriptions(string recipientId, string objectId)
{
return recipientId != null ?
recordsByRec.ContainsKey(recipientId) ? recordsByRec[recipientId].ToList() : new List<SubscriptionRecord>() :
recordsByObj.ContainsKey(objectId ?? string.Empty) ? recordsByObj[objectId ?? string.Empty].ToList() : new List<SubscriptionRecord>();
}
public SubscriptionRecord GetSubscription(string recipientId, string objectId)
{
return recordsByRec.ContainsKey(recipientId) ?
recordsByRec[recipientId].Where(s => s.ObjectId == objectId).FirstOrDefault() :
null;
}
public void SaveSubscription(SubscriptionRecord s)
{
var old = GetSubscription(s.RecipientId, s.ObjectId);
if (old != null)
{
old.Subscribed = s.Subscribed;
}
else
{
records.Add(s);
BuildSubscriptionsIndex(records);
}
}
public void RemoveSubscriptions()
{
records.Clear();
records.Add(s);
BuildSubscriptionsIndex(records);
}
}
public void RemoveSubscriptions(string objectId)
{
records.RemoveAll(s => s.ObjectId == objectId);
BuildSubscriptionsIndex(records);
}
public void RemoveSubscriptions()
{
records.Clear();
BuildSubscriptionsIndex(records);
}
public IEnumerable<SubscriptionMethod> GetSubscriptionMethods(string recipientId)
{
return string.IsNullOrEmpty(recipientId) ?
methods.ToList() :
methodsByRec.ContainsKey(recipientId) ? methodsByRec[recipientId].ToList() : new List<SubscriptionMethod>();
}
public void RemoveSubscriptions(string objectId)
{
records.RemoveAll(s => s.ObjectId == objectId);
BuildSubscriptionsIndex(records);
}
public void SetSubscriptionMethod(SubscriptionMethod m)
{
methods.RemoveAll(r => r.Tenant == m.Tenant && r.SourceId == m.SourceId && r.ActionId == m.ActionId && r.RecipientId == m.RecipientId);
if (m.Methods != null && 0 < m.Methods.Length)
{
methods.Add(m);
}
BuildMethodsIndex(methods);
}
public IEnumerable<SubscriptionMethod> GetSubscriptionMethods(string recipientId)
{
return string.IsNullOrEmpty(recipientId) ?
methods.ToList() :
methodsByRec.ContainsKey(recipientId) ? methodsByRec[recipientId].ToList() : new List<SubscriptionMethod>();
}
private void BuildSubscriptionsIndex(IEnumerable<SubscriptionRecord> records)
public void SetSubscriptionMethod(SubscriptionMethod m)
{
methods.RemoveAll(r => r.Tenant == m.Tenant && r.SourceId == m.SourceId && r.ActionId == m.ActionId && r.RecipientId == m.RecipientId);
if (m.Methods != null && 0 < m.Methods.Length)
{
recordsByRec = records.GroupBy(r => r.RecipientId).ToDictionary(g => g.Key, g => g.ToList());
recordsByObj = records.GroupBy(r => r.ObjectId ?? string.Empty).ToDictionary(g => g.Key, g => g.ToList());
methods.Add(m);
}
BuildMethodsIndex(methods);
}
private void BuildMethodsIndex(IEnumerable<SubscriptionMethod> methods)
{
methodsByRec = methods.GroupBy(r => r.RecipientId).ToDictionary(g => g.Key, g => g.ToList());
}
private void BuildSubscriptionsIndex(IEnumerable<SubscriptionRecord> records)
{
recordsByRec = records.GroupBy(r => r.RecipientId).ToDictionary(g => g.Key, g => g.ToList());
recordsByObj = records.GroupBy(r => r.ObjectId ?? string.Empty).ToDictionary(g => g.Key, g => g.ToList());
}
private void BuildMethodsIndex(IEnumerable<SubscriptionMethod> methods)
{
methodsByRec = methods.GroupBy(r => r.RecipientId).ToDictionary(g => g.Key, g => g.ToList());
}
}
}

View File

@ -28,155 +28,51 @@ using System;
using System.Collections.Generic;
using ASC.Common.Caching;
using ASC.Core.Data;
using ASC.Core.Tenants;
namespace ASC.Core.Caching
{
public class CachedTenantService : ITenantService
public class TenantServiceCache
{
private const string KEY = "tenants";
private readonly ITenantService service;
private readonly ICache cache;
private readonly ICacheNotify<TenantSetting> cacheNotifySettings;
private readonly ICacheNotify<TenantCacheItem> cacheNotifyItem;
public TimeSpan CacheExpiration { get; set; }
public ICache Cache { get; }
public ICacheNotify<TenantCacheItem> CacheNotifyItem { get; }
public ICacheNotify<TenantSetting> CacheNotifySettings { get; }
public TimeSpan SettingsExpiration { get; set; }
public CoreBaseSettings CoreBaseSettings { get; }
public CachedTenantService(ITenantService service, CoreBaseSettings coreBaseSettings, ICacheNotify<TenantCacheItem> cacheNotifyItem, ICacheNotify<TenantSetting> cacheNotifySettings)
public TenantServiceCache(CoreBaseSettings coreBaseSettings, ICacheNotify<TenantCacheItem> cacheNotifyItem, ICacheNotify<TenantSetting> cacheNotifySettings)
{
this.service = service ?? throw new ArgumentNullException("service");
CoreBaseSettings = coreBaseSettings;
cache = AscCache.Memory;
CacheNotifyItem = cacheNotifyItem;
CacheNotifySettings = cacheNotifySettings;
Cache = AscCache.Memory;
CacheExpiration = TimeSpan.FromMinutes(2);
SettingsExpiration = TimeSpan.FromMinutes(2);
cacheNotifyItem.Subscribe((t) =>
{
var tenants = GetTenantStore();
tenants.Remove(t.TenantId);
tenants.Clear(CoreBaseSettings);
tenants.Clear(coreBaseSettings);
}, CacheNotifyAction.InsertOrUpdate);
cacheNotifySettings.Subscribe((s) =>
{
cache.Remove(s.Key);
Cache.Remove(s.Key);
}, CacheNotifyAction.Remove);
}
public void ValidateDomain(string domain)
internal TenantStore GetTenantStore()
{
service.ValidateDomain(domain);
}
public IEnumerable<Tenant> GetTenants(string login, string passwordHash)
{
return service.GetTenants(login, passwordHash);
}
public IEnumerable<Tenant> GetTenants(DateTime from, bool active = true)
{
return service.GetTenants(from, active);
}
public Tenant GetTenant(int id)
{
var tenants = GetTenantStore();
var t = tenants.Get(id);
if (t == null)
{
t = service.GetTenant(id);
if (t != null)
{
tenants.Insert(t);
}
}
return t;
}
public Tenant GetTenant(string domain)
{
var tenants = GetTenantStore();
var t = tenants.Get(domain);
if (t == null)
{
t = service.GetTenant(domain);
if (t != null)
{
tenants.Insert(t);
}
}
return t;
}
public Tenant GetTenantForStandaloneWithoutAlias(string ip)
{
var tenants = GetTenantStore();
var t = tenants.Get(ip);
if (t == null)
{
t = service.GetTenantForStandaloneWithoutAlias(ip);
if (t != null)
{
tenants.Insert(t, ip);
}
}
return t;
}
public Tenant SaveTenant(CoreSettings coreSettings, Tenant tenant)
{
tenant = service.SaveTenant(coreSettings, tenant);
cacheNotifyItem.Publish(new TenantCacheItem() { TenantId = tenant.TenantId }, CacheNotifyAction.InsertOrUpdate);
return tenant;
}
public void RemoveTenant(int id, bool auto = false)
{
service.RemoveTenant(id, auto);
cacheNotifyItem.Publish(new TenantCacheItem() { TenantId = id }, CacheNotifyAction.InsertOrUpdate);
}
public IEnumerable<TenantVersion> GetTenantVersions()
{
return service.GetTenantVersions();
}
public byte[] GetTenantSettings(int tenant, string key)
{
var cacheKey = string.Format("settings/{0}/{1}", tenant, key);
var data = cache.Get<byte[]>(cacheKey);
if (data == null)
{
data = service.GetTenantSettings(tenant, key);
cache.Insert(cacheKey, data ?? new byte[0], DateTime.UtcNow + SettingsExpiration);
}
return data == null ? null : data.Length == 0 ? null : data;
}
public void SetTenantSettings(int tenant, string key, byte[] data)
{
service.SetTenantSettings(tenant, key, data);
var cacheKey = string.Format("settings/{0}/{1}", tenant, key);
cacheNotifySettings.Publish(new TenantSetting { Key = cacheKey }, CacheNotifyAction.Remove);
}
private TenantStore GetTenantStore()
{
var store = cache.Get<TenantStore>(KEY);
var store = Cache.Get<TenantStore>(KEY);
if (store == null)
{
cache.Insert(KEY, store = new TenantStore(), DateTime.UtcNow.Add(CacheExpiration));
Cache.Insert(KEY, store = new TenantStore(), DateTime.UtcNow.Add(CacheExpiration));
}
return store;
}
class TenantStore
internal class TenantStore
{
private readonly Dictionary<int, Tenant> byId = new Dictionary<int, Tenant>();
private readonly Dictionary<string, Tenant> byDomain = new Dictionary<string, Tenant>();
@ -250,4 +146,124 @@ namespace ASC.Core.Caching
}
}
}
public class CachedTenantService : ITenantService
{
private readonly ITenantService service;
private readonly ICache cache;
private readonly ICacheNotify<TenantSetting> cacheNotifySettings;
private readonly ICacheNotify<TenantCacheItem> cacheNotifyItem;
public TimeSpan SettingsExpiration { get; set; }
public TenantServiceCache TenantServiceCache { get; }
public CachedTenantService(DbTenantService service, TenantServiceCache tenantServiceCache)
{
this.service = service ?? throw new ArgumentNullException("service");
cache = AscCache.Memory;
SettingsExpiration = TimeSpan.FromMinutes(2);
TenantServiceCache = tenantServiceCache;
cacheNotifyItem = tenantServiceCache.CacheNotifyItem;
cacheNotifySettings = tenantServiceCache.CacheNotifySettings;
}
public void ValidateDomain(string domain)
{
service.ValidateDomain(domain);
}
public IEnumerable<Tenant> GetTenants(string login, string passwordHash)
{
return service.GetTenants(login, passwordHash);
}
public IEnumerable<Tenant> GetTenants(DateTime from, bool active = true)
{
return service.GetTenants(from, active);
}
public Tenant GetTenant(int id)
{
var tenants = TenantServiceCache.GetTenantStore();
var t = tenants.Get(id);
if (t == null)
{
t = service.GetTenant(id);
if (t != null)
{
tenants.Insert(t);
}
}
return t;
}
public Tenant GetTenant(string domain)
{
var tenants = TenantServiceCache.GetTenantStore();
var t = tenants.Get(domain);
if (t == null)
{
t = service.GetTenant(domain);
if (t != null)
{
tenants.Insert(t);
}
}
return t;
}
public Tenant GetTenantForStandaloneWithoutAlias(string ip)
{
var tenants = TenantServiceCache.GetTenantStore();
var t = tenants.Get(ip);
if (t == null)
{
t = service.GetTenantForStandaloneWithoutAlias(ip);
if (t != null)
{
tenants.Insert(t, ip);
}
}
return t;
}
public Tenant SaveTenant(CoreSettings coreSettings, Tenant tenant)
{
tenant = service.SaveTenant(coreSettings, tenant);
cacheNotifyItem.Publish(new TenantCacheItem() { TenantId = tenant.TenantId }, CacheNotifyAction.InsertOrUpdate);
return tenant;
}
public void RemoveTenant(int id, bool auto = false)
{
service.RemoveTenant(id, auto);
cacheNotifyItem.Publish(new TenantCacheItem() { TenantId = id }, CacheNotifyAction.InsertOrUpdate);
}
public IEnumerable<TenantVersion> GetTenantVersions()
{
return service.GetTenantVersions();
}
public byte[] GetTenantSettings(int tenant, string key)
{
var cacheKey = string.Format("settings/{0}/{1}", tenant, key);
var data = cache.Get<byte[]>(cacheKey);
if (data == null)
{
data = service.GetTenantSettings(tenant, key);
cache.Insert(cacheKey, data ?? new byte[0], DateTime.UtcNow + SettingsExpiration);
}
return data == null ? null : data.Length == 0 ? null : data;
}
public void SetTenantSettings(int tenant, string key, byte[] data)
{
service.SetTenantSettings(tenant, key, data);
var cacheKey = string.Format("settings/{0}/{1}", tenant, key);
cacheNotifySettings.Publish(new TenantSetting { Key = cacheKey }, CacheNotifyAction.Remove);
}
}
}

View File

@ -29,61 +29,146 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ASC.Common.Caching;
using ASC.Core.Data;
using ASC.Core.Tenants;
using ASC.Core.Users;
namespace ASC.Core.Caching
{
public class CachedUserService : IUserService, ICachedService
public class UserServiceCache
{
private const string USERS = "users";
public const string USERS = "users";
private const string GROUPS = "groups";
private const string REFS = "refs";
public const string REFS = "refs";
private readonly IUserService service;
private readonly ICache cache;
private readonly ICacheNotify<UserGroupRefCacheItem> cacheUserGroupRefItem;
private readonly ICacheNotify<UserPhotoCacheItem> cacheUserPhotoItem;
private readonly ICacheNotify<UserInfoCacheItem> cacheUserInfoItem;
private readonly ICacheNotify<GroupCacheItem> cacheGroupCacheItem;
private readonly TrustInterval trustInterval;
private int getchanges;
public TimeSpan CacheExpiration { get; set; }
public TimeSpan DbExpiration { get; set; }
public TimeSpan PhotoExpiration { get; set; }
public TrustInterval TrustInterval { get; set; }
public ICache Cache { get; }
public CoreBaseSettings CoreBaseSettings { get; }
public ICacheNotify<UserInfoCacheItem> CacheUserInfoItem { get; }
public ICacheNotify<UserPhotoCacheItem> CacheUserPhotoItem { get; }
public ICacheNotify<GroupCacheItem> CacheGroupCacheItem { get; }
public ICacheNotify<UserGroupRefCacheItem> CacheUserGroupRefItem { get; }
public CachedUserService(
IUserService service,
public UserServiceCache(
CoreBaseSettings coreBaseSettings,
ICacheNotify<UserInfoCacheItem> cacheUserInfoItem,
ICacheNotify<UserPhotoCacheItem> cacheUserPhotoItem,
ICacheNotify<GroupCacheItem> cacheGroupCacheItem,
ICacheNotify<UserGroupRefCacheItem> cacheUserGroupRefItem
)
ICacheNotify<UserGroupRefCacheItem> cacheUserGroupRefItem)
{
this.service = service ?? throw new ArgumentNullException("service");
TrustInterval = new TrustInterval();
Cache = AscCache.Memory;
CoreBaseSettings = coreBaseSettings;
cache = AscCache.Memory;
trustInterval = new TrustInterval();
CacheExpiration = TimeSpan.FromMinutes(20);
DbExpiration = TimeSpan.FromMinutes(1);
PhotoExpiration = TimeSpan.FromMinutes(10);
CacheUserInfoItem = cacheUserInfoItem;
CacheUserPhotoItem = cacheUserPhotoItem;
CacheGroupCacheItem = cacheGroupCacheItem;
CacheUserGroupRefItem = cacheUserGroupRefItem;
cacheUserInfoItem.Subscribe((u) => InvalidateCache(u), CacheNotifyAction.Any);
cacheUserPhotoItem.Subscribe((p) => cache.Remove(p.Key), CacheNotifyAction.Remove);
cacheUserPhotoItem.Subscribe((p) => Cache.Remove(p.Key), CacheNotifyAction.Remove);
cacheGroupCacheItem.Subscribe((g) => InvalidateCache(), CacheNotifyAction.Any);
cacheUserGroupRefItem.Subscribe((r) => UpdateUserGroupRefCache(r, true), CacheNotifyAction.Remove);
cacheUserGroupRefItem.Subscribe((r) => UpdateUserGroupRefCache(r, false), CacheNotifyAction.InsertOrUpdate);
}
public void InvalidateCache()
{
InvalidateCache(null);
}
private void InvalidateCache(UserInfoCacheItem userInfo)
{
if (CoreBaseSettings.Personal && userInfo != null)
{
var key = GetUserCacheKeyForPersonal(userInfo.Tenant, userInfo.ID.FromByteString());
Cache.Remove(key);
}
TrustInterval.Expire();
}
private void UpdateUserGroupRefCache(UserGroupRef r, bool remove)
{
var key = GetRefCacheKey(r.Tenant);
var refs = Cache.Get<UserGroupRefStore>(key);
if (!remove && refs != null)
{
lock (refs)
{
refs[r.CreateKey()] = r;
}
}
else
{
InvalidateCache();
}
}
public static string GetUserPhotoCacheKey(int tenant, Guid userId)
{
return tenant.ToString() + "userphoto" + userId.ToString();
}
public static string GetGroupCacheKey(int tenant)
{
return tenant.ToString() + GROUPS;
}
public static string GetRefCacheKey(int tenant)
{
return tenant.ToString() + REFS;
}
public static string GetUserCacheKey(int tenant)
{
return tenant.ToString() + USERS;
}
public static string GetUserCacheKeyForPersonal(int tenant, Guid userId)
{
return tenant.ToString() + USERS + userId;
}
}
public class CachedUserService : IUserService, ICachedService
{
private readonly IUserService service;
private readonly ICache cache;
private readonly TrustInterval trustInterval;
private int getchanges;
public TimeSpan CacheExpiration { get; set; }
public TimeSpan DbExpiration { get; set; }
public TimeSpan PhotoExpiration { get; set; }
public CoreBaseSettings CoreBaseSettings { get; }
public UserServiceCache UserServiceCache { get; }
public ICacheNotify<UserInfoCacheItem> CacheUserInfoItem { get; }
public ICacheNotify<UserPhotoCacheItem> CacheUserPhotoItem { get; }
public ICacheNotify<GroupCacheItem> CacheGroupCacheItem { get; }
public ICacheNotify<UserGroupRefCacheItem> CacheUserGroupRefItem { get; }
public CachedUserService(
DbUserService service,
CoreBaseSettings coreBaseSettings,
UserServiceCache userServiceCache
)
{
this.service = service ?? throw new ArgumentNullException("service");
CoreBaseSettings = coreBaseSettings;
UserServiceCache = userServiceCache;
cache = userServiceCache.Cache;
CacheUserInfoItem = userServiceCache.CacheUserInfoItem;
CacheUserPhotoItem = userServiceCache.CacheUserPhotoItem;
CacheGroupCacheItem = userServiceCache.CacheGroupCacheItem;
CacheUserGroupRefItem = userServiceCache.CacheUserGroupRefItem;
trustInterval = userServiceCache.TrustInterval;
CacheExpiration = TimeSpan.FromMinutes(20);
DbExpiration = TimeSpan.FromMinutes(1);
PhotoExpiration = TimeSpan.FromMinutes(10);
}
public IDictionary<Guid, UserInfo> GetUsers(int tenant, DateTime from)
{
@ -124,7 +209,7 @@ namespace ASC.Core.Caching
{
if (!CoreBaseSettings.Personal) return GetUser(tenant, id);
var key = GetUserCacheKeyForPersonal(tenant, id);
var key = UserServiceCache.GetUserCacheKeyForPersonal(tenant, id);
var user = cache.Get<UserInfo>(key);
if (user == null)
@ -148,23 +233,23 @@ namespace ASC.Core.Caching
public UserInfo SaveUser(int tenant, UserInfo user)
{
user = service.SaveUser(tenant, user);
cacheUserInfoItem.Publish(new UserInfoCacheItem { ID = user.ID.ToByteString(), Tenant = tenant }, CacheNotifyAction.Any);
CacheUserInfoItem.Publish(new UserInfoCacheItem { ID = user.ID.ToByteString(), Tenant = tenant }, CacheNotifyAction.Any);
return user;
}
public void RemoveUser(int tenant, Guid id)
{
service.RemoveUser(tenant, id);
cacheUserInfoItem.Publish(new UserInfoCacheItem { Tenant = tenant, ID = id.ToByteString() }, CacheNotifyAction.Any);
CacheUserInfoItem.Publish(new UserInfoCacheItem { Tenant = tenant, ID = id.ToByteString() }, CacheNotifyAction.Any);
}
public byte[] GetUserPhoto(int tenant, Guid id)
{
var photo = cache.Get<byte[]>(GetUserPhotoCacheKey(tenant, id));
var photo = cache.Get<byte[]>(UserServiceCache.GetUserPhotoCacheKey(tenant, id));
if (photo == null)
{
photo = service.GetUserPhoto(tenant, id);
cache.Insert(GetUserPhotoCacheKey(tenant, id), photo, PhotoExpiration);
cache.Insert(UserServiceCache.GetUserPhotoCacheKey(tenant, id), photo, PhotoExpiration);
}
return photo;
}
@ -172,7 +257,7 @@ namespace ASC.Core.Caching
public void SetUserPhoto(int tenant, Guid id, byte[] photo)
{
service.SetUserPhoto(tenant, id, photo);
cacheUserPhotoItem.Publish(new UserPhotoCacheItem { Key = GetUserPhotoCacheKey(tenant, id) }, CacheNotifyAction.Remove);
CacheUserPhotoItem.Publish(new UserPhotoCacheItem { Key = UserServiceCache.GetUserPhotoCacheKey(tenant, id) }, CacheNotifyAction.Remove);
}
public string GetUserPassword(int tenant, Guid id)
@ -208,14 +293,14 @@ namespace ASC.Core.Caching
public Group SaveGroup(int tenant, Group group)
{
group = service.SaveGroup(tenant, group);
cacheGroupCacheItem.Publish(new GroupCacheItem { ID = group.Id.ToString() }, CacheNotifyAction.Any);
CacheGroupCacheItem.Publish(new GroupCacheItem { ID = group.Id.ToString() }, CacheNotifyAction.Any);
return group;
}
public void RemoveGroup(int tenant, Guid id)
{
service.RemoveGroup(tenant, id);
cacheGroupCacheItem.Publish(new GroupCacheItem { ID = id.ToString() }, CacheNotifyAction.Any);
CacheGroupCacheItem.Publish(new GroupCacheItem { ID = id.ToString() }, CacheNotifyAction.Any);
}
@ -223,7 +308,7 @@ namespace ASC.Core.Caching
{
GetChangesFromDb();
var key = GetRefCacheKey(tenant);
var key = UserServiceCache.GetRefCacheKey(tenant);
if (!(cache.Get<UserGroupRefStore>(key) is IDictionary<string, UserGroupRef> refs))
{
refs = service.GetUserGroupRefs(tenant, default);
@ -238,7 +323,7 @@ namespace ASC.Core.Caching
public UserGroupRef SaveUserGroupRef(int tenant, UserGroupRef r)
{
r = service.SaveUserGroupRef(tenant, r);
cacheUserGroupRefItem.Publish(r, CacheNotifyAction.InsertOrUpdate);
CacheUserGroupRefItem.Publish(r, CacheNotifyAction.InsertOrUpdate);
return r;
}
@ -247,23 +332,7 @@ namespace ASC.Core.Caching
service.RemoveUserGroupRef(tenant, userId, groupId, refType);
var r = new UserGroupRef(userId, groupId, refType) { Tenant = tenant };
cacheUserGroupRefItem.Publish(r, CacheNotifyAction.Remove);
}
public void InvalidateCache()
{
InvalidateCache(null);
}
private void InvalidateCache(UserInfoCacheItem userInfo)
{
if (CoreBaseSettings.Personal && userInfo != null)
{
var key = GetUserCacheKeyForPersonal(userInfo.Tenant, userInfo.ID.FromByteString());
cache.Remove(key);
}
trustInterval.Expire();
CacheUserGroupRefItem.Publish(r, CacheNotifyAction.Remove);
}
@ -271,7 +340,7 @@ namespace ASC.Core.Caching
{
GetChangesFromDb();
var key = GetUserCacheKey(tenant);
var key = UserServiceCache.GetUserCacheKey(tenant);
var users = cache.Get<IDictionary<Guid, UserInfo>>(key);
if (users == null)
{
@ -286,7 +355,7 @@ namespace ASC.Core.Caching
{
GetChangesFromDb();
var key = GetGroupCacheKey(tenant);
var key = UserServiceCache.GetGroupCacheKey(tenant);
var groups = cache.Get<IDictionary<Guid, Group>>(key);
if (groups == null)
{
@ -324,7 +393,7 @@ namespace ASC.Core.Caching
//get and merge changes in cached tenants
foreach (var tenantGroup in service.GetUsers(Tenant.DEFAULT_TENANT, starttime).Values.GroupBy(u => u.Tenant))
{
var users = cache.Get<IDictionary<Guid, UserInfo>>(GetUserCacheKey(tenantGroup.Key));
var users = cache.Get<IDictionary<Guid, UserInfo>>(UserServiceCache.GetUserCacheKey(tenantGroup.Key));
if (users != null)
{
lock (users)
@ -339,7 +408,7 @@ namespace ASC.Core.Caching
foreach (var tenantGroup in service.GetGroups(Tenant.DEFAULT_TENANT, starttime).Values.GroupBy(g => g.Tenant))
{
var groups = cache.Get<IDictionary<Guid, Group>>(GetGroupCacheKey(tenantGroup.Key));
var groups = cache.Get<IDictionary<Guid, Group>>(UserServiceCache.GetGroupCacheKey(tenantGroup.Key));
if (groups != null)
{
lock (groups)
@ -354,7 +423,7 @@ namespace ASC.Core.Caching
foreach (var tenantGroup in service.GetUserGroupRefs(Tenant.DEFAULT_TENANT, starttime).Values.GroupBy(r => r.Tenant))
{
var refs = cache.Get<UserGroupRefStore>(GetRefCacheKey(tenantGroup.Key));
var refs = cache.Get<UserGroupRefStore>(UserServiceCache.GetRefCacheKey(tenantGroup.Key));
if (refs != null)
{
lock (refs)
@ -374,46 +443,10 @@ namespace ASC.Core.Caching
}
}
private void UpdateUserGroupRefCache(UserGroupRef r, bool remove)
{
var key = GetRefCacheKey(r.Tenant);
var refs = cache.Get<UserGroupRefStore>(key);
if (!remove && refs != null)
{
lock (refs)
{
refs[r.CreateKey()] = r;
}
}
else
{
InvalidateCache();
}
}
private static string GetUserPhotoCacheKey(int tenant, Guid userId)
public void InvalidateCache()
{
return tenant.ToString() + "userphoto" + userId.ToString();
}
private static string GetGroupCacheKey(int tenant)
{
return tenant.ToString() + GROUPS;
}
private static string GetRefCacheKey(int tenant)
{
return tenant.ToString() + REFS;
}
private static string GetUserCacheKey(int tenant)
{
return tenant.ToString() + USERS;
}
private static string GetUserCacheKeyForPersonal(int tenant, Guid userId)
{
return tenant.ToString() + USERS + userId;
UserServiceCache.InvalidateCache();
}
[Serializable]

View File

@ -186,7 +186,7 @@ namespace ASC.Core
public Tenant GetCurrentTenant(bool throwIfNotFound)
{
return GetCurrentTenant(throwIfNotFound, HttpContext ?? ASC.Common.HttpContext.Current);
return GetCurrentTenant(throwIfNotFound, HttpContext);
}
public void SetCurrentTenant(Tenant tenant)

View File

@ -26,7 +26,6 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using ASC.Common.Data;
using ASC.Common.Data.Sql;
@ -38,8 +37,8 @@ namespace ASC.Core.Data
{
public class DbAzService : DbBaseService, IAzService
{
public DbAzService(ConnectionStringSettings connectionString, DbRegistry dbRegistry)
: base(connectionString, dbRegistry, "tenant")
public DbAzService(DbOptionsManager dbOptionsManager)
: base(dbOptionsManager, "tenant")
{
}

View File

@ -37,6 +37,7 @@ namespace ASC.Core.Data
private readonly string dbid;
public DbRegistry DbRegistry { get; }
public DbOptionsManager DbOptionsManager { get; }
protected string TenantColumn
{
get;
@ -50,6 +51,12 @@ namespace ASC.Core.Data
TenantColumn = tenantColumn;
}
protected DbBaseService(DbOptionsManager dbOptionsManager, string tenantColumn)
{
DbOptionsManager = dbOptionsManager;
TenantColumn = tenantColumn;
}
protected T ExecScalar<T>(ISqlInstruction sql)
{
return Execute(db => db.ExecuteScalar<T>(sql));
@ -77,7 +84,7 @@ namespace ASC.Core.Data
protected IDbManager GetDb()
{
return DbManager.FromHttpContext(DbRegistry, dbid);
return DbOptionsManager?.Value;
}
protected SqlQuery Query(string table, int tenant)
@ -108,7 +115,7 @@ namespace ASC.Core.Data
private T Execute<T>(Func<IDbManager, T> action)
{
using var db = GetDb();
var db = GetDb();
return action(db);
}
}

View File

@ -26,7 +26,6 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using ASC.Common.Data;
using ASC.Common.Data.Sql;
@ -40,9 +39,8 @@ namespace ASC.Core.Data
private const string tenants_quota = "tenants_quota";
internal const string tenants_quotarow = "tenants_quotarow";
public DbQuotaService(ConnectionStringSettings connectionString, DbRegistry dbRegistry)
: base(connectionString, dbRegistry, "tenant")
public DbQuotaService(DbOptionsManager dbOptionsManager)
: base(dbOptionsManager, "tenant")
{
}

View File

@ -26,7 +26,6 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using ASC.Common.Data;
using ASC.Common.Data.Sql;
@ -37,8 +36,8 @@ namespace ASC.Core.Data
{
public class DbSubscriptionService : DbBaseService, ISubscriptionService
{
public DbSubscriptionService(ConnectionStringSettings connectionString, DbRegistry dbRegistry)
: base(connectionString, dbRegistry, "tenant")
public DbSubscriptionService(DbOptionsManager dbOptionsManager)
: base(dbOptionsManager, "tenant")
{
}

View File

@ -26,10 +26,10 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using ASC.Common.Data;
using ASC.Common.Data.Sql;
using ASC.Common.Data.Sql.Expressions;
@ -47,8 +47,8 @@ namespace ASC.Core.Data
public TenantDomainValidator TenantDomainValidator { get; }
public TimeZoneConverter TimeZoneConverter { get; }
public DbTenantService(ConnectionStringSettings connectionString, DbRegistry dbRegistry, TenantDomainValidator tenantDomainValidator, TimeZoneConverter timeZoneConverter)
: base(connectionString, dbRegistry, null)
public DbTenantService(DbOptionsManager dbOptionsManager, TenantDomainValidator tenantDomainValidator, TimeZoneConverter timeZoneConverter)
: base(dbOptionsManager, null)
{
TenantDomainValidator = tenantDomainValidator;
TimeZoneConverter = timeZoneConverter;

View File

@ -26,7 +26,6 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using ASC.Common.Data;
using ASC.Common.Data.Sql;
@ -39,8 +38,8 @@ namespace ASC.Core.Data
{
public class DbUserService : DbBaseService, IUserService
{
public DbUserService(ConnectionStringSettings connectionString, DbRegistry dbRegistry)
: base(connectionString, dbRegistry, "tenant")
public DbUserService(DbOptionsManager dbOptionsManager)
: base(dbOptionsManager, "tenant")
{
}
@ -213,7 +212,7 @@ namespace ASC.Core.Data
user.LastModified = DateTime.UtcNow;
user.Tenant = tenant;
using (var db = GetDb())
var db = GetDb();
using (var tx = db.BeginTransaction())
{
user.UserName = user.UserName.Trim();

View File

@ -78,6 +78,7 @@ namespace ASC.Core
{
}
//TODO:fix
public HostedSolution(
IConfiguration configuration,
TenantDomainValidator tenantDomainValidator,
@ -88,13 +89,13 @@ namespace ASC.Core
IOptionsMonitor<LogNLog> options,
string region)
{
tenantService = new DbTenantService(connectionString, dbRegistry, tenantDomainValidator, timeZoneConverter);
tenantService = new DbTenantService(null, null, null);
var baseSettings = new CoreBaseSettings(configuration);
coreSettings = new CoreSettings(tenantService, baseSettings, configuration);
userService = new DbUserService(connectionString, dbRegistry);
quotaService = new DbQuotaService(connectionString, dbRegistry);
tariffService = new TariffService(connectionString, quotaService, tenantService, baseSettings, coreSettings, configuration, dbRegistry, tariffServiceStorage, options);
userService = new DbUserService(null);
quotaService = new DbQuotaService(null);
tariffService = new TariffService(quotaService, tenantService, baseSettings, coreSettings, configuration, null, tariffServiceStorage, options);
clientTenantManager = new TenantManager(tenantService, quotaService, tariffService, null, baseSettings, coreSettings);
settingsManager = new DbSettingsManager(connectionString);
Region = region ?? string.Empty;

View File

@ -51,6 +51,7 @@ namespace ASC.Core
public TimeZoneConverter TimeZoneConverter { get; }
public CookieStorage CookieStorage { get; }
public DbRegistry DbRegistry { get; }
public DbOptionsManager DbOptions { get; }
public TariffServiceStorage TariffServiceStorage { get; }
public IOptionsMonitor<LogNLog> Options { get; }
@ -60,6 +61,7 @@ namespace ASC.Core
TimeZoneConverter timeZoneConverter,
CookieStorage cookieStorage,
DbRegistry dbRegistry,
DbOptionsManager dbOptions,
TariffServiceStorage tariffServiceStorage,
IOptionsMonitor<LogNLog> options)
{
@ -69,6 +71,7 @@ namespace ASC.Core
TimeZoneConverter = timeZoneConverter;
CookieStorage = cookieStorage;
DbRegistry = dbRegistry;
DbOptions = dbOptions;
TariffServiceStorage = tariffServiceStorage;
Options = options;
Initialize();
@ -190,12 +193,12 @@ namespace ASC.Core
public IDbManager GetRegionDb(string region)
{
return new DbManager(DbRegistry, GetRegionService(region).DbId);
return DbOptions.Get(GetRegionService(region).DbId);
}
public IDbManager GetMultiRegionDb()
{
return new MultiRegionalDbManager(GetRegions().Select(r => new DbManager(DbRegistry, GetRegionService(r).DbId)));
return new MultiRegionalDbManager(GetRegions().Select(r => DbOptions.Get(GetRegionService(r).DbId)));
}
public System.Configuration.ConnectionStringSettings GetRegionConnectionString(string region)
@ -264,7 +267,7 @@ namespace ASC.Core
{
try
{
using var db = new DbManager(DbRegistry, connectionString.Name);
using var db = DbOptions.Get(connectionString.Name);
var q = new SqlQuery("regions")
.Select("region")
.Select("connection_string")

View File

@ -30,9 +30,7 @@ namespace ASC.Core.Common.Tests
using System.Linq;
using ASC.Common.Caching;
using ASC.Common.Data;
using ASC.Common.Utils;
using ASC.Core.Caching;
using ASC.Core.Data;
using Microsoft.Extensions.Configuration;
using NUnit.Framework;
@ -44,7 +42,7 @@ namespace ASC.Core.Common.Tests
public CachedSubscriptionServiceTest(IConfiguration configuration, DbRegistry dbRegistry, ICacheNotify<SubscriptionRecord> cacheNotify, ICacheNotify<SubscriptionMethodCache> notify)
{
service = new CachedSubscriptionService(new DbSubscriptionService(configuration.GetConnectionStrings("core"), dbRegistry), cacheNotify, notify);
service = new CachedSubscriptionService(null, null);
}

View File

@ -41,6 +41,13 @@ namespace ASC.Core.Common.Tests
[TestFixture]
public class DbQuotaServiceTest : DbBaseTest<DbQuotaService>
{
public DbOptionsManager DbOptionsManager { get; }
public DbQuotaServiceTest(DbOptionsManager dbOptionsManager)
{
DbOptionsManager = dbOptionsManager;
}
[OneTimeSetUp]
public void ClearData()
{
@ -136,7 +143,7 @@ namespace ASC.Core.Common.Tests
private void DeleteQuotaRow(TenantQuotaRow row)
{
var d = new SqlDelete(DbQuotaService.tenants_quotarow).Where("tenant", row.Tenant).Where("path", row.Path);
using var dbManager = new DbManager(null, "core", null);
var dbManager = DbOptionsManager.Value;
dbManager.ExecuteNonQuery(d);
}
}

View File

@ -29,7 +29,6 @@ namespace ASC.Core.Common.Tests
{
using System;
using System.Linq;
using ASC.Common.Utils;
using ASC.Core.Data;
using ASC.Core.Tenants;
using ASC.Core.Users;
@ -44,7 +43,7 @@ namespace ASC.Core.Common.Tests
public DbTenantServiceTest()
{
userService = new DbUserService(Configuration.GetConnectionStrings("core"), DbRegistry);
userService = new DbUserService(null);
}

View File

@ -28,14 +28,7 @@
namespace ASC.Core.Common.Tests
{
using System;
using ASC.Common.Data;
using ASC.Common.Logging;
using ASC.Common.Utils;
using ASC.Core.Billing;
using ASC.Core.Data;
using ASC.Core.Tenants;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using NUnit.Framework;
[TestFixture]
@ -44,12 +37,9 @@ namespace ASC.Core.Common.Tests
private readonly ITariffService tariffService;
public TariffServiceTest(IConfiguration configuration, TenantDomainValidator tenantDomainValidator, TimeZoneConverter timeZoneConverter, DbRegistry dbRegistry, TariffServiceStorage tariffServiceStorage, IOptionsMonitor<LogNLog> options)
public TariffServiceTest()
{
var cs = configuration.GetConnectionStrings("core");
var tenantService = new DbTenantService(cs, dbRegistry, tenantDomainValidator, timeZoneConverter);
var baseSettings = new CoreBaseSettings(configuration);
tariffService = new TariffService(cs, new DbQuotaService(cs, dbRegistry), tenantService, baseSettings, new CoreSettings(tenantService, baseSettings, configuration), configuration, dbRegistry, tariffServiceStorage, options);
tariffService = new TariffService(null, null, null, null, null, null, null, null);
}

View File

@ -49,7 +49,7 @@ namespace ASC.Core.Common.Tests
public TariffSyncServiceTest()
{
tariffSyncService = new TariffSyncService(ServiceProvider, Configuration, DbRegistry, Options);
tariffSyncService = new TariffSyncService(null, null, null, null);
}
[Test]

View File

@ -42,18 +42,18 @@ namespace ASC.Feed.Data
public AuthContext AuthContext { get; }
public TenantManager TenantManager { get; }
public TenantUtil TenantUtil { get; }
public DbRegistry DbRegistry { get; }
public DbOptionsManager DbOptionsManager { get; }
public FeedAggregateDataProvider(DbRegistry dbRegistry)
public FeedAggregateDataProvider(DbOptionsManager dbOptionsManager)
{
DbRegistry = dbRegistry;
DbOptionsManager = dbOptionsManager;
}
public FeedAggregateDataProvider(AuthContext authContext, TenantManager tenantManager, TenantUtil tenantUtil, DbRegistry dbRegistry)
public FeedAggregateDataProvider(AuthContext authContext, TenantManager tenantManager, TenantUtil tenantUtil, DbOptionsManager dbOptionsManager)
{
AuthContext = authContext;
TenantManager = tenantManager;
TenantUtil = tenantUtil;
DbRegistry = dbRegistry;
DbOptionsManager = dbOptionsManager;
}
public DateTime GetLastTimeAggregate(string key)
@ -62,17 +62,15 @@ namespace ASC.Feed.Data
.Select("last_date")
.Where("last_key", key);
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
var db = GetDb();
var value = db.ExecuteScalar<DateTime>(q);
return value != default ? value.AddSeconds(1) : value;
}
public void SaveFeeds(IEnumerable<FeedRow> feeds, string key, DateTime value)
{
using (var db = new DbManager(DbRegistry, Constants.FeedDbId))
{
db.ExecuteNonQuery(new SqlInsert("feed_last", true).InColumnValue("last_key", key).InColumnValue("last_date", value));
}
var db = GetDb();
db.ExecuteNonQuery(new SqlInsert("feed_last", true).InColumnValue("last_key", key).InColumnValue("last_date", value));
const int feedsPortionSize = 1000;
var aggregatedDate = DateTime.UtcNow;
@ -94,7 +92,7 @@ namespace ASC.Feed.Data
private void SaveFeedsPortion(IEnumerable<FeedRow> feeds, DateTime aggregatedDate)
{
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
var db = GetDb();
using var tx = db.BeginTransaction();
var i = new SqlInsert("feed_aggregate", true)
.InColumns("id", "tenant", "product", "module", "author", "modified_by", "group_id", "created_date",
@ -131,12 +129,12 @@ namespace ASC.Feed.Data
public void RemoveFeedAggregate(DateTime fromTime)
{
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
var db = GetDb();
using var command = db.Connection.CreateCommand();
using var tx = db.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
command.Transaction = tx;
command.CommandTimeout = 60 * 60; // a hour
var dialect = DbRegistry.GetSqlDialect(Constants.FeedDbId);
var dialect = db.GetSqlDialect(Constants.FeedDbId);
if (dialect.SupportMultiTableUpdate)
{
command.ExecuteNonQuery("delete from feed_aggregate, feed_users using feed_aggregate, feed_users where id = feed_id and aggregated_date < @date", new { date = fromTime });
@ -228,7 +226,7 @@ namespace ASC.Feed.Data
query.Where(exp);
}
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
var db = GetDb();
var news = db
.ExecuteList(query)
.ConvertAll(r => new FeedResultItem(
@ -259,13 +257,13 @@ namespace ASC.Feed.Data
q.Where(Exp.Ge("a.aggregated_date", lastReadedTime));
}
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
var db = GetDb();
return db.ExecuteList(q).Count();
}
public IEnumerable<int> GetTenants(TimeInterval interval)
{
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
var db = GetDb();
var q = new SqlQuery("feed_aggregate")
.Select("tenant")
.Where(Exp.Between("aggregated_date", interval.From, interval.To))
@ -279,7 +277,7 @@ namespace ASC.Feed.Data
.Select("a.json, a.module, a.author, a.modified_by, a.group_id, a.created_date, a.modified_date, a.aggregated_date")
.Where("a.id", id);
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
var db = GetDb();
var news = db
.ExecuteList(query)
.ConvertAll(r => new FeedResultItem(
@ -298,19 +296,21 @@ namespace ASC.Feed.Data
public void RemoveFeedItem(string id)
{
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
var db = GetDb();
using var command = db.Connection.CreateCommand();
using var tx = db.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
command.Transaction = tx;
command.CommandTimeout = 60 * 60; // a hour
var dialect = DbRegistry.GetSqlDialect(Constants.FeedDbId);
var dialect = db.GetSqlDialect(Constants.FeedDbId);
command.ExecuteNonQuery(new SqlDelete("feed_users").Where("feed_id", id), dialect);
command.ExecuteNonQuery(new SqlDelete("feed_aggregate").Where("id", id), dialect);
tx.Commit();
}
private IDbManager GetDb() => DbOptionsManager.Get(Constants.FeedDbId);
}

View File

@ -39,13 +39,13 @@ namespace ASC.Feed.Data
public AuthContext AuthContext { get; }
public TenantManager TenantManager { get; }
public DbRegistry DbRegistry { get; }
public DbOptionsManager DbOptionsManager { get; }
public FeedReadedDataProvider(AuthContext authContext, TenantManager tenantManager, DbRegistry dbRegistry)
public FeedReadedDataProvider(AuthContext authContext, TenantManager tenantManager, DbOptionsManager dbOptionsManager)
{
AuthContext = authContext;
TenantManager = tenantManager;
DbRegistry = dbRegistry;
DbOptionsManager = dbOptionsManager;
}
public DateTime GetTimeReaded()
@ -117,7 +117,7 @@ namespace ASC.Feed.Data
private DbManager GetDb()
{
return new DbManager(DbRegistry, dbId);
return DbOptionsManager.Get(dbId);
}
private int GetTenant()

View File

@ -47,16 +47,16 @@ namespace ASC.Resource.Manager
private const string ResAuthorsLangTable = "res_authorslang";
private const string ResAuthorsFileTable = "res_authorsfile";
public DbRegistry DbRegistry { get; }
public DbOptionsManager DbOptionsManager { get; }
public ResourceData(DbRegistry dbRegistry)
public ResourceData(DbOptionsManager dbOptionsManager)
{
DbRegistry = dbRegistry;
DbOptionsManager = dbOptionsManager;
}
public DateTime GetLastUpdate()
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResFilesTable).SelectMax("LastUpdate");
return dbManager.ExecuteScalar<DateTime>(sql);
@ -64,7 +64,7 @@ namespace ASC.Resource.Manager
public List<ResCulture> GetListLanguages(int fileId, string title)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResCultureTable)
.Select("res_cultures.title", "res_cultures.value", "res_cultures.available")
.LeftOuterJoin("res_data", Exp.EqColumns("res_cultures.title", "res_data.cultureTitle"))
@ -80,7 +80,7 @@ namespace ASC.Resource.Manager
public Dictionary<ResCulture, List<string>> GetCulturesWithAuthors()
{
using var dbManager = new DbManager(DbRegistry, "tmresource");
var dbManager = GetDb();
var sql = new SqlQuery("res_authorslang ral")
.Select(new[] { "ral.authorLogin", "rc.title", "rc.value" })
.InnerJoin("res_cultures rc", Exp.EqColumns("rc.title", "ral.cultureTitle"))
@ -94,7 +94,7 @@ namespace ASC.Resource.Manager
public void AddCulture(string cultureTitle, string name)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sqlInsert = new SqlInsert(ResCultureTable);
sqlInsert.InColumnValue("title", cultureTitle).InColumnValue("value", name);
dbManager.ExecuteNonQuery(sqlInsert);
@ -102,7 +102,7 @@ namespace ASC.Resource.Manager
public void AddResource(string cultureTitle, string resType, DateTime date, ResWord word, bool isConsole, string authorLogin, bool updateIfExist = true)
{
using var db = new DbManager(DbRegistry, Dbid);
var db = GetDb();
var resData = db.ExecuteScalar<string>(GetQuery(ResDataTable, cultureTitle, word));
var resReserve = db.ExecuteScalar<string>(GetQuery(ResReserveTable, cultureTitle, word));
@ -166,7 +166,7 @@ namespace ASC.Resource.Manager
public void EditEnglish(ResWord word)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var update = new SqlUpdate(ResDataTable);
update.Set("textvalue", word.ValueFrom).Where("fileID", word.ResFile.FileID).Where("title", word.Title).Where("cultureTitle", "Neutral");
dbManager.ExecuteNonQuery(update);
@ -174,7 +174,7 @@ namespace ASC.Resource.Manager
public void AddComment(ResWord word)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sqlUpdate = new SqlUpdate(ResDataTable);
sqlUpdate.Set("description", word.TextComment).Where("title", word.Title).Where("fileID", word.ResFile.FileID).Where("cultureTitle", "Neutral");
dbManager.ExecuteNonQuery(sqlUpdate);
@ -189,7 +189,7 @@ namespace ASC.Resource.Manager
fileName = fileNameWithoutExtension.Split('.')[0] + Path.GetExtension(fileName);
}
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResFilesTable)
.SelectCount()
.Where("resName", fileName)
@ -220,7 +220,7 @@ namespace ASC.Resource.Manager
public IEnumerable<ResCulture> GetCultures()
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResCultureTable);
sql.Select("title", "value", "available")
.OrderBy("title", true);
@ -230,7 +230,7 @@ namespace ASC.Resource.Manager
public void SetCultureAvailable(string title)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlUpdate(ResCultureTable);
sql.Set("available", true).Where("title", title);
dbManager.ExecuteNonQuery(sql);
@ -243,7 +243,7 @@ namespace ASC.Resource.Manager
public List<ResFile> GetAllFiles()
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResFilesTable);
return dbManager.ExecuteList(sql.SelectAll()).Select(r => new ResFile
@ -257,7 +257,7 @@ namespace ASC.Resource.Manager
public IEnumerable<ResWord> GetListResWords(ResCurrent current, string search)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var exist = new SqlQuery(ResDataTable + " rd3")
.Select("rd3.title")
.Where("rd3.fileid = rd1.fileid")
@ -313,7 +313,7 @@ namespace ASC.Resource.Manager
public List<ResWord> GetListResWords(ResFile resFile, string to, string search)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResDataTable)
.Select("title", "fileid", "textValue", "description", "flag", "link")
.InnerJoin(ResFilesTable, Exp.EqColumns(ResFilesTable + ".ID", ResDataTable + ".fileID"))
@ -335,7 +335,7 @@ namespace ASC.Resource.Manager
public void GetListModules(ResCurrent currentData)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var notExist = new SqlQuery(ResDataTable + " rd1")
.Select("1")
.Where("rd1.fileid = rd.fileid")
@ -372,7 +372,7 @@ namespace ASC.Resource.Manager
public void LockModules(string projectName, string modules)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sqlUpdate = new SqlUpdate(ResFilesTable);
sqlUpdate.Set("isLock", 1).Where("projectName", projectName).Where(Exp.In("moduleName", modules.Split(',')));
dbManager.ExecuteNonQuery(sqlUpdate);
@ -380,7 +380,7 @@ namespace ASC.Resource.Manager
public void UnLockModules()
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sqlUpdate = new SqlUpdate(ResFilesTable);
sqlUpdate.Set("isLock", 0);
dbManager.ExecuteNonQuery(sqlUpdate);
@ -388,7 +388,7 @@ namespace ASC.Resource.Manager
public void AddLink(string resource, string fileName, string page)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var query = new SqlQuery(ResDataTable);
query.Select(ResDataTable + ".id")
.InnerJoin(ResFilesTable, Exp.EqColumns(ResFilesTable + ".id", ResDataTable + ".fileid"))
@ -403,7 +403,7 @@ namespace ASC.Resource.Manager
public void GetResWordByKey(ResWord word, string to)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResDataTable)
.Select("textvalue", "description", "link")
.Where("fileID", word.ResFile.FileID)
@ -433,7 +433,7 @@ namespace ASC.Resource.Manager
public void GetValueByKey(ResWord word, string to)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResDataTable);
sql.Select("textvalue")
.Where("fileID", word.ResFile.FileID)
@ -456,7 +456,7 @@ namespace ASC.Resource.Manager
public List<Author> GetListAuthors()
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResAuthorsTable)
.Select("login", "password", "isAdmin");
@ -465,7 +465,7 @@ namespace ASC.Resource.Manager
public Author GetAuthor(string login)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResAuthorsTable)
.Select("login", "password", "isAdmin")
.Where("login", login);
@ -514,7 +514,7 @@ namespace ASC.Resource.Manager
public void CreateAuthor(Author author, IEnumerable<string> languages, string modules)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sqlInsert = new SqlInsert(ResAuthorsTable, true)
.InColumnValue("login", author.Login)
.InColumnValue("password", author.Password)
@ -555,7 +555,7 @@ namespace ASC.Resource.Manager
public List<ResWord> SearchAll(string projectName, string moduleName, string languageTo, string searchText, string searchType)
{
using var dbManager = new DbManager(DbRegistry, Dbid);
var dbManager = GetDb();
var sql = new SqlQuery(ResDataTable)
.Select("title", "fileid", "textValue", "resName", "moduleName", "projectName")
.InnerJoin(ResFilesTable, Exp.EqColumns(ResFilesTable + ".ID", ResDataTable + ".fileID"))
@ -578,7 +578,7 @@ namespace ASC.Resource.Manager
public void UpdateHashTable(ref Hashtable table, DateTime date)
{
using var dbManager = new DbManager(DbRegistry, "tmresourceTrans");
var dbManager = GetDb("tmresourceTrans");
var sql = new SqlQuery(ResDataTable)
.Select(ResDataTable + ".textValue", ResDataTable + ".title", ResFilesTable + ".ResName", ResDataTable + ".cultureTitle")
.InnerJoin(ResFilesTable, Exp.EqColumns(ResFilesTable + ".id", ResDataTable + ".fileID"))
@ -597,6 +597,10 @@ namespace ASC.Resource.Manager
}
}
private IDbManager GetDb(string dbId = null)
{
return DbOptionsManager.Get(dbId ?? Dbid);
}
private static ResWord GetWord(IList<object> r)
{

View File

@ -1,4 +1,3 @@
using System.Configuration;
using ASC.Api.Core;
using ASC.Api.Core.Auth;
@ -117,85 +116,22 @@ namespace ASC.People
.AddSingleton(typeof(ILog), typeof(LogNLog))
.AddStorage(Configuration)
.AddWebItemManager()
.AddSingleton((r) =>
{
var DbRegistry = r.GetService<DbRegistry>();
var cs = DbRegistry.GetConnectionString("core");
if (cs == null)
{
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
}
return (ISubscriptionService)new CachedSubscriptionService(new DbSubscriptionService(cs, DbRegistry), r.GetService<ICacheNotify<SubscriptionRecord>>(), r.GetService<ICacheNotify<SubscriptionMethodCache>>());
})
.AddSingleton((r) =>
{
var DbRegistry = r.GetService<DbRegistry>();
var cs = DbRegistry.GetConnectionString("core");
if (cs == null)
{
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
}
return (IAzService)new CachedAzService(new DbAzService(cs, DbRegistry), r.GetService<ICacheNotify<AzRecordCache>>());
})
.AddSingleton((r) =>
{
var DbRegistry = r.GetService<DbRegistry>();
var cs = DbRegistry.GetConnectionString("core");
if (cs == null)
{
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
}
return (IUserService)new CachedUserService(new DbUserService(cs, DbRegistry), r.GetService<CoreBaseSettings>(), r.GetService<ICacheNotify<UserInfoCacheItem>>(), r.GetService<ICacheNotify<UserPhotoCacheItem>>(), r.GetService<ICacheNotify<GroupCacheItem>>(), r.GetService<ICacheNotify<UserGroupRefCacheItem>>());
})
.AddSingleton((r) =>
{
var DbRegistry = r.GetService<DbRegistry>();
var cs = DbRegistry.GetConnectionString("core");
if (cs == null)
{
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
}
return (ITenantService)new CachedTenantService(new DbTenantService(cs, DbRegistry, r.GetService<TenantDomainValidator>(), r.GetService<TimeZoneConverter>()), r.GetService<CoreBaseSettings>(), r.GetService<ICacheNotify<TenantCacheItem>>(), r.GetService<ICacheNotify<TenantSetting>>());
})
.AddSingleton((r) =>
{
var DbRegistry = r.GetService<DbRegistry>();
var quotaCacheEnabled = false;
if (Configuration["core:enable-quota-cache"] == null)
{
quotaCacheEnabled = true;
}
else
{
quotaCacheEnabled = !bool.TryParse(Configuration["core:enable-quota-cache"], out var enabled) || enabled;
}
var cs = DbRegistry.GetConnectionString("core");
if (cs == null)
{
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
}
return quotaCacheEnabled ? (IQuotaService)new CachedQuotaService(new DbQuotaService(cs, DbRegistry), r.GetService<ICacheNotify<QuotaCacheItem>>()) : new DbQuotaService(cs, DbRegistry);
})
.AddSingleton((r) =>
{
var DbRegistry = r.GetService<DbRegistry>();
var cs = DbRegistry.GetConnectionString("core");
if (cs == null)
{
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
}
return (ITariffService)new TariffService(cs,
r.GetService<IQuotaService>(),
r.GetService<ITenantService>(),
r.GetService<CoreBaseSettings>(),
r.GetService<CoreSettings>(),
Configuration,
DbRegistry,
r.GetService<TariffServiceStorage>(),
r.GetService<IOptionsMonitor<LogNLog>>()
);
})
.AddScoped<DbSubscriptionService>()
.AddScoped<ISubscriptionService, CachedSubscriptionService>()
.AddSingleton<SubscriptionServiceCache>()
.AddScoped<DbAzService>()
.AddScoped<IAzService, CachedAzService>()
.AddSingleton<AzServiceCache>()
.AddSingleton<UserServiceCache>()
.AddScoped<DbUserService>()
.AddScoped<IUserService, CachedUserService>()
.AddSingleton<TenantServiceCache>()
.AddScoped<DbTenantService>()
.AddScoped<ITenantService, CachedTenantService>()
.AddSingleton<QuotaServiceCache>()
.AddScoped<DbQuotaService>()
.AddScoped<IQuotaService, CachedQuotaService>()
.AddScoped<ITariffService, TariffService>()
.AddScoped<ApiContext>()
.AddScoped<StudioNotifyService>()
.AddScoped<UserManagerWrapper>()
@ -252,7 +188,7 @@ namespace ASC.People
.AddScoped<FileUtility>()
.AddScoped<LicenseReader>()
.AddScoped<ApiSystemHelper>()
.AddSingleton<CoreSettings>()
.AddScoped<CoreSettings>()
.AddSingleton<WebPathSettings>()
.AddSingleton<BaseStorageSettingsListener>()
.AddSingleton<CoreBaseSettings>()

View File

@ -74,7 +74,7 @@ namespace ASC.Web.Core.Mail
public DbRegistry DbRegistry { get; }
public CoreBaseSettings CoreBaseSettings { get; }
public MailServiceHelperStorage MailServiceHelperStorage { get; }
public DbOptionsManager DbOptions { get; }
public ICache Cache { get; }
public MailServiceHelper(
@ -83,7 +83,8 @@ namespace ASC.Web.Core.Mail
IConfiguration configuration,
DbRegistry dbRegistry,
CoreBaseSettings coreBaseSettings,
MailServiceHelperStorage mailServiceHelperStorage)
MailServiceHelperStorage mailServiceHelperStorage,
DbOptionsManager dbOptions)
{
UserManager = userManager;
AuthContext = authContext;
@ -91,6 +92,7 @@ namespace ASC.Web.Core.Mail
DbRegistry = dbRegistry;
CoreBaseSettings = coreBaseSettings;
MailServiceHelperStorage = mailServiceHelperStorage;
DbOptions = dbOptions;
Cache = mailServiceHelperStorage.Cache;
DefaultDatabase = GetDefaultDatabase();
}
@ -103,7 +105,7 @@ namespace ASC.Web.Core.Mail
private DbManager GetDb()
{
return new DbManager(DbRegistry, "webstudio");
return DbOptions.Get("webstudio");
}
private DbManager GetDb(string dbid, string connectionString)
@ -117,7 +119,7 @@ namespace ASC.Web.Core.Mail
DbRegistry.RegisterDatabase(connectionSettings.Name, connectionSettings);
return new DbManager(DbRegistry, connectionSettings.Name);
return DbOptions.Get(connectionSettings.Name);
}
private void DemandPermission()

View File

@ -99,7 +99,7 @@ namespace ASC.Web.Studio.Core.Notify
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
var apiSystemHelper = scope.ServiceProvider.GetService<ApiSystemHelper>();
var setupInfo = scope.ServiceProvider.GetService<SetupInfo>();
var dbRegistry = scope.ServiceProvider.GetService<DbRegistry>();
var options = scope.ServiceProvider.GetService<DbOptionsManager>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
var tariff = paymentManager.GetTariff(tenant.TenantId);
@ -200,12 +200,11 @@ namespace ASC.Web.Studio.Core.Notify
.Where(Exp.Le("created_date", now.AddDays(-1)))
.GroupBy("short_date");
using (var db = new DbManager(dbRegistry, dbid))
{
datesWithActivity = db
.ExecuteList(query)
.ConvertAll(r => Convert.ToDateTime(r[0]));
}
var db = options.Get(dbid);
datesWithActivity = db
.ExecuteList(query)
.ConvertAll(r => Convert.ToDateTime(r[0]));
if (datesWithActivity.Count < 5)
{
@ -559,7 +558,7 @@ namespace ASC.Web.Studio.Core.Notify
var tenantExtra = scope.ServiceProvider.GetService<TenantExtra>();
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
var dbRegistry = scope.ServiceProvider.GetService<DbRegistry>();
var options = scope.ServiceProvider.GetService<DbOptionsManager>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
var tariff = paymentManager.GetTariff(tenant.TenantId);
@ -690,12 +689,11 @@ namespace ASC.Web.Studio.Core.Notify
.Where(Exp.Le("created_date", now.AddDays(-1)))
.GroupBy("short_date");
using (var db = new DbManager(dbRegistry, dbid))
{
datesWithActivity = db
.ExecuteList(query)
.ConvertAll(r => Convert.ToDateTime(r[0]));
}
var db = options.Get(dbid);
datesWithActivity = db
.ExecuteList(query)
.ConvertAll(r => Convert.ToDateTime(r[0]));
if (datesWithActivity.Count < 5)
{