This commit is contained in:
2022-02-16 10:47:45 +00:00
parent 5d15b28456
commit 4a394d3ff7
75 changed files with 3127 additions and 691 deletions
@@ -20,7 +20,6 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
{
//-------------------------------------------------------------------
// Data members.
private readonly SaxInternals internals;
private readonly String alias_ActivityIndex = SaxActivityMgr_Dbas.aliasActivityIndex;
private readonly String alias_ActivityIndex_UserActivity = SaxActivityMgr_Dbas.aliasActivityIndex_UserActivity;
protected class IndexStatsData
@@ -35,13 +34,11 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
protected SaxActivityConsole_Web(SaxSessionContext sessionContext) :
base(sessionContext)
{
internals = new SaxInternals(sessionContext);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
internals.Dispose();
}
base.Dispose(disposing);
}
@@ -78,8 +75,8 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
if (!context.IsValid()) return results;
// Columns to query.
ColumnDfn colItemType = internals.ActivityMgr.GetActivityIndexColumnDfn(SaxActivityIndex.Column.ItemType);
ColumnDfn colItemId = internals.ActivityMgr.GetActivityIndexColumnDfn(SaxActivityIndex.Column.ItemId);
ColumnDfn colItemType = Internals.ActivityMgr.GetActivityIndexColumnDfn(SaxActivityIndex.Column.ItemType);
ColumnDfn colItemId = Internals.ActivityMgr.GetActivityIndexColumnDfn(SaxActivityIndex.Column.ItemId);
String colDataNameEffectiveOn = "EffectiveOn";
// Query the Activity Index.
@@ -102,7 +99,7 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
prmActivityIndex.Alias_ActivityIndex = alias_ActivityIndex;
prmActivityIndex.ResultsPaging.PageNo = 1;
prmActivityIndex.ResultsPaging.PageLength = 100;
query.Filters.AddRange(internals.ActivityMgr.GetActivityIndexQueryFilter(prmActivityIndex));
query.Filters.AddRange(Internals.ActivityMgr.GetActivityIndexQueryFilter(prmActivityIndex));
// First pass, note the activity Item and effective date.
List<ActivityData_Web> activityDataList = new List<ActivityData_Web>();
@@ -382,7 +379,7 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
List<IndexEntryData> indexEntryDataList = GetEntriesForIndex(indexData);
// Retrieve existing index entries for the item.
List<SaxActivityIndex> indexEntries = internals.ActivityMgr.GetActivityIndexListForItem(indexData.ItemId);
List<SaxActivityIndex> indexEntries = Internals.ActivityMgr.GetActivityIndexListForItem(indexData.ItemId);
foreach (SaxActivityIndex indexEntry in indexEntries)
{
// Is the index entry still required.
@@ -396,9 +393,9 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
if (!indexEntry.EffectiveOn.Equals(indexEntrydata.EffectiveOn))
{
indexEntry.EffectiveOn = indexEntrydata.EffectiveOn;
if (internals.ActivityMgr.UpdateActivityIndex(indexEntry, dbUpdateInfo))
if (Internals.ActivityMgr.UpdateActivityIndex(indexEntry, dbUpdateInfo))
stats.EntriesUpdated++;
else SaLogger.Warn(fn + " Failed to update Activity Index - " + internals.ActivityMgr.ErrorStateMessage);
else SaLogger.Warn(fn + " Failed to update Activity Index - " + Internals.ActivityMgr.ErrorStateMessage);
}
// Remove the entry from the 'required' list.
// Entries remaining in this list will be created.
@@ -407,18 +404,18 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
else
{
// Index entry no longer required.
if (internals.ActivityMgr.DeleteActivityIndex(indexEntry, dbUpdateInfo))
if (Internals.ActivityMgr.DeleteActivityIndex(indexEntry, dbUpdateInfo))
stats.EntriesDeleted++;
else SaLogger.Warn(fn + " Failed to delete Activity Index - " + internals.ActivityMgr.ErrorStateMessage);
else SaLogger.Warn(fn + " Failed to delete Activity Index - " + Internals.ActivityMgr.ErrorStateMessage);
}
}
// The remaining required Index entries will be created.
foreach (IndexEntryData indexEntry in indexEntryDataList)
{
SaxActivityIndex itemIndexEntry = internals.ActivityMgr.CreateActivityIndex(indexEntry.ItemId, indexEntry.SportId, indexEntry.RegionId, indexEntry.EffectiveOn);
if (internals.ActivityMgr.InsertActivityIndex(itemIndexEntry, dbUpdateInfo))
SaxActivityIndex itemIndexEntry = Internals.ActivityMgr.CreateActivityIndex(indexEntry.ItemId, indexEntry.SportId, indexEntry.RegionId, indexEntry.EffectiveOn);
if (Internals.ActivityMgr.InsertActivityIndex(itemIndexEntry, dbUpdateInfo))
stats.EntriesInserted++;
else SaLogger.Warn(fn + " Failed to insert Activity Index - " + internals.ActivityMgr.ErrorStateMessage);
else SaLogger.Warn(fn + " Failed to insert Activity Index - " + Internals.ActivityMgr.ErrorStateMessage);
}
// Log statistics.
@@ -506,7 +503,7 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
if (!ItemId.IsValid(activityItemId)) return SetErrorState("Activity item id must be specified");
DateTime now = DateTime.Now;
SaxUserActivity userActivity = internals.ActivityMgr.GetUserActivityForUserItem(userAccountId, activityItemId);
SaxUserActivity userActivity = Internals.ActivityMgr.GetUserActivityForUserItem(userAccountId, activityItemId);
if (userActivity != null)
{
// Update activity.
@@ -515,10 +512,10 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
userActivity.ViewedAtFirst = now;
userActivity.ViewedAtLast = now;
userActivity.Status = SaxUserActivity.DefaultStatus;
if (!internals.ActivityMgr.UpdateUserActivity(userActivity, dbUpdateInfo))
if (!Internals.ActivityMgr.UpdateUserActivity(userActivity, dbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to update User Activity for viewing: " + internals.ActivityMgr.ErrorStateMessage);
return SetErrorState(internals.ActivityMgr.ErrorStateMessage);
SaLogger.Warn(fn + " Failed to update User Activity for viewing: " + Internals.ActivityMgr.ErrorStateMessage);
return SetErrorState(Internals.ActivityMgr.ErrorStateMessage);
}
}
else
@@ -538,7 +535,7 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
if (!ItemId.IsValid(activityItemId)) return SetErrorState("Activity item id must be specified");
DateTime now = DateTime.Now;
SaxUserActivity userActivity = internals.ActivityMgr.GetUserActivityForUserItem(userAccountId, activityItemId);
SaxUserActivity userActivity = Internals.ActivityMgr.GetUserActivityForUserItem(userAccountId, activityItemId);
if (userActivity != null)
{
if (userActivity.Reaction != activityReaction)
@@ -553,10 +550,10 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
userActivity.ReactedAtFirst = now;
userActivity.ReactedAtLast = now;
userActivity.Status = SaxUserActivity.DefaultStatus;
if (!internals.ActivityMgr.UpdateUserActivity(userActivity, dbUpdateInfo))
if (!Internals.ActivityMgr.UpdateUserActivity(userActivity, dbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to update User Activity with reaction: " + internals.ActivityMgr.ErrorStateMessage);
return SetErrorState(internals.ActivityMgr.ErrorStateMessage);
SaLogger.Warn(fn + " Failed to update User Activity with reaction: " + Internals.ActivityMgr.ErrorStateMessage);
return SetErrorState(Internals.ActivityMgr.ErrorStateMessage);
}
}
}
@@ -134,39 +134,46 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
{
String fn = GetType().Name + ".RefreshRegions";
if (!RegionsSupported) throw new NotSupportedException(fn + " Regions not supported.");
SaLogger.Info(fn + " START.", false);
DateTime startedAt = DateTime.Now;
// Refreshed lists will be populated in isolation and then used to instantaneously replace the cache lists.
Dictionary<SysId, SaxRegion.Data> newRegionDataMap = new Dictionary<SysId, SaxRegion.Data>();
List<SaxRegion.Data> newActiveRegionDataList = new List<SaxRegion.Data>();
// Query Regions to replace cache.
SaxRegion.Params prmRegion = new SaxRegion.Params();
prmRegion.StatusCat = SaxRegion.StatusCat.NotDeleted;
foreach (SaxRegion region in data.internals.ReferenceMgr.GetRegionList(prmRegion))
try
{
// Only interested in retaining the Data objects.
newRegionDataMap[region.Id] = region.GetData();
region.Dispose();
}
DateTime startedAt = DateTime.Now;
// Populate replacement list of active regions.
foreach (SaxRegion.Data regionData in newRegionDataMap.GetValues())
{
if (IsRegionActive(newRegionDataMap, regionData))
newActiveRegionDataList.Add(regionData.Clone());
}
// Refreshed lists will be populated in isolation and then used to instantaneously replace the cache lists.
Dictionary<SysId, SaxRegion.Data> newRegionDataMap = new Dictionary<SysId, SaxRegion.Data>();
List<SaxRegion.Data> newActiveRegionDataList = new List<SaxRegion.Data>();
// Replace the list of Regions.
lock (regionsData)
{
// Assign the refreshed regions and active regions.
// NB The old regions don't need to be disposed as they are SaxRegion.Data objects.
regionsData.regionDataMap = newRegionDataMap;
regionsData.activeRegionDataList = newActiveRegionDataList;
// Query Regions to replace cache.
SaxRegion.Params prmRegion = new SaxRegion.Params();
prmRegion.StatusCat = SaxRegion.StatusCat.NotDeleted;
foreach (SaxRegion region in data.internals.ReferenceMgr.GetRegionList(prmRegion))
{
// Only interested in retaining the Data objects.
newRegionDataMap[region.Id] = region.GetData();
region.Dispose();
}
// Populate replacement list of active regions.
foreach (SaxRegion.Data regionData in newRegionDataMap.GetValues())
{
if (IsRegionActive(newRegionDataMap, regionData))
newActiveRegionDataList.Add(regionData.Clone());
}
// Replace the list of Regions.
lock (regionsData)
{
// Assign the refreshed regions and active regions.
// NB The old regions don't need to be disposed as they are SaxRegion.Data objects.
regionsData.regionDataMap = newRegionDataMap;
regionsData.activeRegionDataList = newActiveRegionDataList;
}
SaLogger.Info(fn + " Regions found: " + regionsData.regionDataMap.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds));
}
catch (Exception exc)
{
SaLogger.Error(fn + ExceptionUtil.GetLogMessage(exc, "refreshing Regions cache"));
}
SaLogger.Info(fn + " END. Regions found: " + regionsData.regionDataMap.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds));
}
private static bool IsRegionActive(Dictionary<SysId, SaxRegion.Data> regionDataMap, SaxRegion.Data regionData)
{
@@ -223,39 +230,46 @@ namespace Saxonite.Net.Core.Web.Base.Consoles
{
String fn = GetType().Name + ".RefreshSports";
if (!SportsSupported) throw new NotSupportedException(fn + " Sports not supported.");
SaLogger.Info(fn + " START.", false);
DateTime startedAt = DateTime.Now;
// Refreshed lists will be populated in isolation and then used to instantaneously replace the cache lists.
Dictionary<SysId, SaxSport.Data> newSportDataMap = new Dictionary<SysId, SaxSport.Data>();
List<SaxSport.Data> newActiveSportDataList = new List<SaxSport.Data>();
// Query Sports to replace cache.
SaxSport.Params prmSport = new SaxSport.Params();
prmSport.StatusCat = SaxSport.StatusCat.NotDeleted;
foreach (SaxSport sport in data.internals.ReferenceMgr.GetSportList(prmSport))
try
{
// Only interested in retaining the Data objects.
newSportDataMap[sport.Id] = sport.GetData();
sport.Dispose();
}
DateTime startedAt = DateTime.Now;
// Populate replacement list of active sports.
foreach (SaxSport.Data sportData in newSportDataMap.GetValues())
{
if (IsSportActive(newSportDataMap, sportData))
newActiveSportDataList.Add(sportData.Clone());
}
// Refreshed lists will be populated in isolation and then used to instantaneously replace the cache lists.
Dictionary<SysId, SaxSport.Data> newSportDataMap = new Dictionary<SysId, SaxSport.Data>();
List<SaxSport.Data> newActiveSportDataList = new List<SaxSport.Data>();
// Replace the list of Sports.
lock (sportsData)
{
// Assign the refreshed sports and active sports.
// NB The old sports don't need to be disposed as they are SaxSport.Data objects.
sportsData.sportDataMap = newSportDataMap;
sportsData.activeSportDataList = newActiveSportDataList;
// Query Sports to replace cache.
SaxSport.Params prmSport = new SaxSport.Params();
prmSport.StatusCat = SaxSport.StatusCat.NotDeleted;
foreach (SaxSport sport in data.internals.ReferenceMgr.GetSportList(prmSport))
{
// Only interested in retaining the Data objects.
newSportDataMap[sport.Id] = sport.GetData();
sport.Dispose();
}
// Populate replacement list of active sports.
foreach (SaxSport.Data sportData in newSportDataMap.GetValues())
{
if (IsSportActive(newSportDataMap, sportData))
newActiveSportDataList.Add(sportData.Clone());
}
// Replace the list of Sports.
lock (sportsData)
{
// Assign the refreshed sports and active sports.
// NB The old sports don't need to be disposed as they are SaxSport.Data objects.
sportsData.sportDataMap = newSportDataMap;
sportsData.activeSportDataList = newActiveSportDataList;
}
SaLogger.Info(fn + " Sports found: " + sportsData.sportDataMap.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds));
}
catch (Exception exc)
{
SaLogger.Error(fn + ExceptionUtil.GetLogMessage(exc, "refreshing Sports cache"));
}
SaLogger.Info(fn + " END. Sports found: " + sportsData.sportDataMap.Count + ". Elapsed: " + DateUtil.FormatNumberOfSeconds((DateTime.Now - startedAt).TotalSeconds));
}
private static bool IsSportActive(Dictionary<SysId, SaxSport.Data> sportDataMap, SaxSport.Data sportData)
{
@@ -0,0 +1,37 @@
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Consoles;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Saxonite.Net.Core.Web.Base.Consoles
{
//=======================================================================
public abstract class SaxSessionDataConsole_Web : SaxSessionDataConsole
{
//-------------------------------------------------------------------
// Definitions.
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
protected SaxSessionDataConsole_Web(SaxSessionContext sessionContext) :
base(sessionContext)
{
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -43,6 +43,7 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
// Protected construction.
protected SaxController_Base(SaxLocaliser localiser)
{
CreatedAt = DateTime.Now;
Localiser = localiser;
// Initialise console (debug) logging listener.
@@ -60,6 +61,7 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
//-------------------------------------------------------------------
// Properties.
public DateTime CreatedAt { get; }
public bool DebugMode { get; } = SacsSystem.DebugMode;
protected SaxApplication_Web App { get { return SaxApplication_Web.WebApp; } }
public SaxAppConfig AppConfig { get { return App.AppConfig; } }
@@ -102,6 +104,7 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
public SaxInternals Internals { get { if (internals == null) internals = new SaxInternals(SessionContext); return internals; } }
// Consoles.
public SaxDataCacheConsole DataCacheConsole { get { return Internals.DataCacheConsole; } }
public SaxSessionDataConsole SessionDataConsole { get { return Internals.SessionDataConsole; } }
public SaxActivityConsole ActivityConsole { get { return Internals.ActivityConsole; } }
// Managers.
public SaxReferenceMgr ReferenceMgr { get { return Internals.ReferenceMgr; } }
@@ -161,7 +164,7 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
//-------------------------------------------------------------------
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (DebugMode) SaLogger.Debug(GetType().Name + ".OnActionExecuting" + (ViewData.Model != null ? " Model: " + ViewData.Model : ""));
//if (DebugMode) SaLogger.Debug(GetType().Name + ".OnActionExecuting" + (ViewData.Model != null ? " Model: " + ViewData.Model : ""));
// Refreh model properties.
SaxModel_Base baseModel = ViewData.Model as SaxModel_Base;
@@ -171,7 +174,7 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (DebugMode) SaLogger.Debug(GetType().Name + ".OnActionExecuted" + (ViewData.Model != null ? " Model: " + ViewData.Model : ""));
//if (DebugMode) SaLogger.Debug(GetType().Name + ".OnActionExecuted" + (ViewData.Model != null ? " Model: " + ViewData.Model : ""));
// Refreh model properties.
SaxModel_Base baseModel = ViewData.Model as SaxModel_Base;
@@ -296,7 +299,17 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
//-------------------------------------------------------------------
// Session.
//-------------------------------------------------------------------
public bool ValidUserSession { get { return SessionData?.ValidUserSession ?? false; } }
public bool ValidUserSession
{
get
{
if (SessionData == null || !SessionData.ValidUserSession) return false;
SaxSessionDataConsole sessionDataConsole = SessionDataConsole;
if (sessionDataConsole != null)
sessionDataConsole.RecordUserActive(UserAccountId, CreatedAt);
return true;
}
}
public SysId UserAccountId { get { return SessionData?.User?.UserAccountId ?? null; } }
public DbUpdateInfo DbUpdateInfo { get { return SessionData?.DbUpdateInfo ?? new DbUpdateInfo(null, "", SaxSystem.ComputerName); } }
// Referrer.
+21 -3
View File
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Mvc.Rendering;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
@@ -63,6 +64,7 @@ namespace Saxonite.Net.Core.Web.Base.Models
protected SaxInternals Internals { get { if (internals == null) internals = new SaxInternals(SessionContext); return internals; } }
// Consoles.
protected SaxDataCacheConsole DataCacheConsole { get { return Internals.DataCacheConsole; } }
protected SaxSessionDataConsole SessionDataConsole { get { return Internals.SessionDataConsole; } }
protected SaxActivityConsole ActivityConsole { get { return Internals.ActivityConsole; } }
// Managers.
public SaxReferenceMgr ReferenceMgr { get { return Internals.ReferenceMgr; } }
@@ -189,8 +191,10 @@ namespace Saxonite.Net.Core.Web.Base.Models
}
public bool IsPaged { get { return paging.Paged; } }
public uint PageNo { get { return paging.PageNo; } set { paging.PageNo = value; } }
public String PageNoValue { get { return paging.PageNo.ToString(); } set { paging.PageNo = (uint)StringUtil.ToInt(value); } }
public ushort PageLength { get { return paging.PageLength; } set { paging.PageLength = value; } }
public uint PageCount { get { return (PageLength > 0 ? (uint)Math.Ceiling((decimal)ItemTotal / PageLength) : 0); } }
public String PageLengthValue { get { return paging.PageLength.ToString(); } set { paging.PageLength = (ushort)StringUtil.ToShort(value); } }
public uint PageCount { get { return (PageLength > 0 ? (uint)Math.Ceiling((decimal)ItemTotal / paging.PageLength) : 0); } }
public ushort ItemCount { get; set; }
private ulong itemTotal = 0;
public ulong ItemTotal
@@ -241,6 +245,17 @@ namespace Saxonite.Net.Core.Web.Base.Models
return maxLength;
}
//-------------------------------------------------------------------
// Display data - Dates.
public String FormatDateForDisplay(DateTime value)
{
return DateUtil.Format(value, "d-MMM-yy", SessionCulture);
}
public String FormatDateTimeForDisplay(DateTime value)
{
return StringUtil.TrimAll(DateUtil.Format(value, "d-MMM-yy HH:mm", SessionCulture));
}
//-------------------------------------------------------------------
// Form data - Dates.
// Format may depend on locale, but as long as these methods are used consistently,
@@ -362,13 +377,16 @@ namespace Saxonite.Net.Core.Web.Base.Models
}
}
/// <summary>List of Organisation Categories for dropdown.</summary>
/// <summary>
/// List of Organisation Categories for dropdown.
/// <para>NB Does not include 'Partner' or 'Other'.</para>
/// </summary>
public IEnumerable<SelectListItem> OrganisationCategoriesForSelect
{
get
{
List<SelectListItem> values = new List<SelectListItem>();
foreach (TypeCodeDesc organisationCategory in OrganisationCategoryCodes)
foreach (TypeCodeDesc organisationCategory in OrganisationCategoryCodes.FindAll(item => item.Type != (int)Sax.OrganisationCategory.Partner && item.Type != (int)Sax.OrganisationCategory.Other))
values.Add(new SelectListItem(Localiser.GetOrganisationCategoryCaption((Sax.OrganisationCategory)organisationCategory.Type), organisationCategory.Code));
return values;
}