using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; using Saxonite.Net.Standard.Base.Mgr; using Saxonite.Net.Standard.Base.App; using System; using System.Collections.Generic; using System.Text; using Saxonite.Net.Standard.Base.Consoles; using Saxonite.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Utils; using Saxonite.Net.Standard.Base.Mgr.Support; using Saxonite.Net.Standard.Base.Mgr.Reference; namespace Saxonite.Net.Standard.Base.App { //======================================================================= public class SaxInternals : SacsDisposable { //------------------------------------------------------------------- // Data members. private class DataMembers { public bool useDataCacheConsole; } private readonly DataMembers data = new DataMembers(); private class Managers { public SaxReferenceMgr referenceMgr = null; public SaxAccountMgr accountMgr = null; public SaxActivityMgr activityMgr = null; public SaxItemDataMgr itemDataMgr = null; // Reference. public SaxReferenceGolfMgr referenceGolfMgr = null; // Support. public SaxSupportMgr supportMgr = null; } private readonly Managers mgr = new Managers(); private class Consoles { public SaxActivityConsole activityConsole; public SaxEmailConsole emailConsole; } private readonly Consoles con = new Consoles(); //------------------------------------------------------------------- // Construction. public SaxInternals(SaxSessionContext sessionContext, bool useDataCacheConsole = true) { if (sessionContext == null) throw new NotSupportedException("Unable to create Internals with invalid session context"); data.useDataCacheConsole = useDataCacheConsole; System = SaxGlobals.System; SessionContext = sessionContext; try { // Check for data cache. // NB Must not do this if Internals constructed by the DataCache console itself as cached data will not be requested from here. if (useDataCacheConsole) { // Inside try..catch as Admin app throws exception on GetDataCacheConsole(). SaxDataCacheConsole dataCacheConsole = SaxGlobals.ConsoleHelper.GetDataCacheConsole(SessionContext); if (dataCacheConsole != null) dataCacheConsole.PopulateCachedDataToInternals(this); } } catch (Exception) { } } protected override void Dispose(bool disposing) { if (disposing) { if (mgr.referenceMgr != null) mgr.referenceMgr.Dispose(); mgr.referenceMgr = null; if (mgr.accountMgr != null) mgr.accountMgr.Dispose(); mgr.accountMgr = null; if (mgr.activityMgr != null) mgr.activityMgr.Dispose(); mgr.activityMgr = null; if (mgr.itemDataMgr != null) mgr.itemDataMgr.Dispose(); mgr.itemDataMgr = null; if (mgr.referenceGolfMgr != null) mgr.referenceGolfMgr.Dispose(); mgr.referenceGolfMgr = null; if (mgr.supportMgr != null) mgr.supportMgr.Dispose(); mgr.supportMgr = null; if (con.activityConsole != null) con.activityConsole.Dispose(); con.activityConsole = null; } } //------------------------------------------------------------------- // Properties. public bool DebugMode { get; } = SacsSystem.DebugMode; public SaxSystem System { get; } public SaxSessionContext SessionContext { get; } public ISacsDatabase CoreDatabase { get { return SaxGlobals.App.GetDatabase(SessionContext, Sax.Database.Core); } } public IDatabaseInfo CreateCoreDbInfo() { return SaxGlobals.App.CreateDbInfo(SessionContext, Sax.Database.Core); } //------------------------------------------------------------------- // System codes. private readonly Dictionary> codeTypes = new Dictionary>(); public List GetCodesOfType(Sax.CodeType codeType) { if (!codeTypes.ContainsKey(codeType)) codeTypes.Add(codeType, SaxSystem.GetCodesOfType(codeType)); return new List(codeTypes[codeType]); } public List DataItemTypeCodes { get { return GetCodesOfType(Sax.CodeType.DataItemType); } } public List YesNoCodes { get { return GetCodesOfType(Sax.CodeType.YesNo); } } public List GenderCodes { get { return GetCodesOfType(Sax.CodeType.Gender); } } public List SportGroupingCodes { get { return GetCodesOfType(Sax.CodeType.SportGrouping); } } public List SportSpecialityLabelCodes { get { return GetCodesOfType(Sax.CodeType.SportSpecialityLabel); } } public List SportContactTypeCodes { get { return GetCodesOfType(Sax.CodeType.SportContactType); } } public List SportParticipatingCodes { get { return GetCodesOfType(Sax.CodeType.SportParticipating); } } public List SportPreparingCodes { get { return GetCodesOfType(Sax.CodeType.SportPreparing); } } public List SportOfficiatingCodes { get { return GetCodesOfType(Sax.CodeType.SportOfficiating); } } public List RegionTypeCodes { get { return GetCodesOfType(Sax.CodeType.RegionType); } } public List EligibilityTypeCodes { get { return GetCodesOfType(Sax.CodeType.EligibilityType); } } public List UserRoleCodes { get { return GetCodesOfType(Sax.CodeType.UserRole); } } public List OrganisationTypeCodes { get { return GetCodesOfType(Sax.CodeType.OrganisationType); } } public List OrganisationCategoryCodes { get { return GetCodesOfType(Sax.CodeType.OrganisationCategory); } } public List OrganisationRoleCodes { get { return GetCodesOfType(Sax.CodeType.OrganisationRole); } } public List AssociationTypeCodes { get { return GetCodesOfType(Sax.CodeType.AssociationType); } } public List AddressTypeCodes { get { return GetCodesOfType(Sax.CodeType.AddressType); } } public List ContactMethodCodes { get { return GetCodesOfType(Sax.CodeType.ContactMethod); } } public List EventTypeCodes { get { return GetCodesOfType(Sax.CodeType.EventType); } } public List OpportunityTypeCodes { get { return GetCodesOfType(Sax.CodeType.OpportunityType); } } public List ActivityReactionCodes { get { return GetCodesOfType(Sax.CodeType.ActivityReaction); } } // Support. public List UserReportTypeCodes { get { return GetCodesOfType(Sax.CodeType.UserReportType); } } public List SupportItemProcessTypeCodes { get { return GetCodesOfType(Sax.CodeType.SupportItemProcessType); } } //------------------------------------------------------------------- // Consoles. public SaxConsoleHelper ConsoleHelper { get { return SaxGlobals.App.ConsoleHelper; } } public SaxDataCacheConsole DataCacheConsole { get { return SaxGlobals.ConsoleHelper.GetDataCacheConsole(SessionContext); } } public SaxSessionDataConsole SessionDataConsole { get { return SaxGlobals.ConsoleHelper.GetSessionDataConsole(SessionContext); } } public SaxActivityConsole ActivityConsole { get { if (con.activityConsole == null) con.activityConsole = ConsoleHelper.CreateActivityConsole(SessionContext); return con.activityConsole; } } public SaxEmailConsole EmailConsole { get { if (con.emailConsole == null) con.emailConsole = ConsoleHelper.CreateEmailConsole(SessionContext); return con.emailConsole; } } //------------------------------------------------------------------- // Managers. public SaxReferenceMgr ReferenceMgr { get { if (mgr.referenceMgr == null) mgr.referenceMgr = System.CreateReferenceMgr(SessionContext, this); return mgr.referenceMgr; } } public SaxAccountMgr AccountMgr { get { if (mgr.accountMgr == null) mgr.accountMgr = System.CreateAccountMgr(SessionContext, this); return mgr.accountMgr; } } public SaxActivityMgr ActivityMgr { get { if (mgr.activityMgr == null) mgr.activityMgr = System.CreateActivityMgr(SessionContext, this); return mgr.activityMgr; } } public SaxItemDataMgr ItemDataMgr { get { if (mgr.itemDataMgr == null) mgr.itemDataMgr = System.CreateItemDataMgr(SessionContext, this); return mgr.itemDataMgr; } } public SaxReferenceGolfMgr ReferenceGolfMgr { get { if (mgr.referenceGolfMgr == null) mgr.referenceGolfMgr = System.CreateReferenceGolfMgr(SessionContext, this); return mgr.referenceGolfMgr; } } public SaxSupportMgr SupportMgr { get { if (mgr.supportMgr == null) mgr.supportMgr = System.CreateSupportMgr(SessionContext, this); return mgr.supportMgr; } } //------------------------------------------------------------------- // Regions. // NB Online application caches regions and sports so these may be pre-populated in the Internals. // Otherwise they are populated on first request. private readonly Dictionary regionCache = new Dictionary(); private bool regionCacheFullyPopulated = false; public void PopulateRegionCache(List regions) { foreach (SaxRegion.Data regionData in regions) regionCache[regionData.Id] = regionData.Clone(); regionCacheFullyPopulated = true; //if (DebugMode) SaLogger.Debug($"{SysUtil.Fn}(regions) Regions populated: {regionCache.Count}."); } public void RefreshRegionCache() { if (regionCacheFullyPopulated) return; DateTime startedAt = DateTime.Now; SaxRegion.Params prmRegion = new SaxRegion.Params(); prmRegion.StatusCat = SaxRegion.StatusCat.NotDeleted; int regionsQueried = 0; foreach (SaxRegion region in ReferenceMgr.GetRegionList(prmRegion)) { regionsQueried++; regionCache[region.Id] = region.GetData(); region.Dispose(); } regionCacheFullyPopulated = true; SaLogger.Debug($"{SysUtil.Fn} Regions queried: {regionsQueried}. Regions in cache: {regionCache.Count}. Elapsed: {DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds)}."); } private void QueryRegionsToCache(List regionsIds) { if (regionCacheFullyPopulated) return; SaxRegion.Params prmRegion = new SaxRegion.Params(); prmRegion.IdsIncluded.AddRange(regionsIds.FindAll(item => SysId.IsValid(item) && !regionCache.ContainsKey(item))); prmRegion.StatusCat = SaxRegion.StatusCat.NotDeleted; if (prmRegion.IdsIncluded.Count > 0) { // At least one region needs to be retrieved. DateTime startedAt = DateTime.Now; int regionsQueried = 0; foreach (SaxRegion region in ReferenceMgr.GetRegionList(prmRegion)) { regionsQueried++; regionCache[region.Id] = region.GetData(); region.Dispose(); } SaLogger.Debug($"{SysUtil.Fn}(regionIds) Regions queried: {regionsQueried}. Regions in cache: {regionCache.Count}. Elapsed: {DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds)}."); } } public SaxRegion.Data GetRegion(SysId regionId) { QueryRegionsToCache(new List() { regionId }); return regionCache.GetValue(regionId, null); } public List GetRegions(List regionIds) { List regions = new List(); QueryRegionsToCache(regionIds); foreach (SysId regionId in regionIds) { if (!SysId.IsValid(regionId)) continue; SaxRegion.Data region = regionCache.GetValue(regionId, null); if (region != null) regions.Add(region); } return regions; } //------------------------------------------------------------------- // Sports. // NB Online application caches sports and sports so these may be pre-populated in the Internals. // Otherwise they are populated on first request. private readonly Dictionary sportCache = new Dictionary(); private bool sportCacheFullyPopulated = false; public void PopulateSportCache(List sports) { foreach (SaxSport.Data sportData in sports) sportCache[sportData.Id] = sportData.Clone(); sportCacheFullyPopulated = true; //if (DebugMode) SaLogger.Debug($"{SysUtil.Fn}(sports) Sports populated: {sportCache.Count}."); } public void RefreshSportCache() { if (sportCacheFullyPopulated) return; DateTime startedAt = DateTime.Now; SaxSport.Params prmSport = new SaxSport.Params(); prmSport.StatusCat = SaxSport.StatusCat.NotDeleted; int sportsQueried = 0; foreach (SaxSport sport in ReferenceMgr.GetSportList(prmSport)) { sportsQueried++; sportCache[sport.Id] = sport.GetData(); sport.Dispose(); } sportCacheFullyPopulated = true; SaLogger.Debug($"{SysUtil.Fn} Sports queried: {sportsQueried}. Sports in cache: {sportCache.Count}. Elapsed: {DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds)}."); } private void QuerySportsToCache(List sportsIds) { if (sportCacheFullyPopulated) return; SaxSport.Params prmSport = new SaxSport.Params(); prmSport.IdsIncluded.AddRange(sportsIds.FindAll(item => SysId.IsValid(item) && !sportCache.ContainsKey(item))); prmSport.StatusCat = SaxSport.StatusCat.NotDeleted; if (prmSport.IdsIncluded.Count > 0) { // At least one sport needs to be retrieved. DateTime startedAt = DateTime.Now; int sportsQueried = 0; foreach (SaxSport sport in ReferenceMgr.GetSportList(prmSport)) { sportsQueried++; sportCache[sport.Id] = sport.GetData(); sport.Dispose(); } SaLogger.Debug($"{SysUtil.Fn}(sportIds) Sports queried: {sportsQueried}. Sports in cache: {sportCache.Count}. Elapsed: {DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds)}."); } } public SaxSport.Data GetSport(SysId sportId) { QuerySportsToCache(new List() { sportId }); return sportCache.GetValue(sportId, null); } public List GetSports(List sportIds) { List sports = new List(); QuerySportsToCache(sportIds); foreach (SysId sportId in sportIds) { if (!SysId.IsValid(sportId)) continue; SaxSport.Data sport = sportCache.GetValue(sportId, null); if (sport != null) sports.Add(sport); } return sports; } //------------------------------------------------------------------- // Common Data Components //------------------------------------------------------------------- // User Accounts. private readonly Dictionary userAccountCache = new Dictionary(); public SaxUserAccount GetUserAccount(SysId userAccountId) { if (!SysId.IsValid(userAccountId)) return null; if (!userAccountCache.ContainsKey(userAccountId)) userAccountCache.Add(userAccountId, AccountMgr.GetUserAccountById(userAccountId)); return userAccountCache.GetValue(userAccountId, null); } public String GetUserAccountEmailAddress(SysId userAccountId) { SaxUserAccount userAccount = GetUserAccount(userAccountId); return userAccount?.EmailAddress ?? ""; } public String GetUserAccountDisplayName(SysId userAccountId) { SaxUserAccount userAccount = GetUserAccount(userAccountId); return userAccount?.GetDisplayName() ?? ""; } //------------------------------------------------------------------- // User Accounts. private readonly Dictionary organisationCache = new Dictionary(); public SaxOrganisation GetOrganisation(SysId organisationId) { if (!SysId.IsValid(organisationId)) return null; if (!organisationCache.ContainsKey(organisationId)) organisationCache.Add(organisationId, AccountMgr.GetOrganisationById(organisationId)); return organisationCache.GetValue(organisationId, null); } public String GetOrganisationName(SysId organisationId) { SaxOrganisation organisation = GetOrganisation(organisationId); return organisation?.Name ?? ""; } public SysId GetOrganisationRegionId(SysId organisationId) { SaxOrganisation organisation = GetOrganisation(organisationId); return organisation?.RegionIdPrimary ?? new SysId(); } //------------------------------------------------------------------- } //======================================================================= }