This commit is contained in:
@@ -4,28 +4,23 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOiIxNTcxODU5OTU0IiwiZXhwIjoiMTU3MjQ
|
||||
|
||||
|
||||
## IMMEDIATE ITEMS
|
||||
TODO: Ensure scaleability by checking for performance issues now before replicating code (particularly in widget etc)
|
||||
- As per this document https://docs.microsoft.com/en-us/aspnet/core/performance/performance-best-practices?view=aspnetcore-3.1
|
||||
- For scaleability go back to async only for any db calls functions like creating widgets etc
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UPDATE SPEC DOCS with new format and names etc or at least remove nonsense as necessary
|
||||
|
||||
UPDATE MANUAL API REGARDING LISTS
|
||||
|
||||
|
||||
TODO: REFACTOR GetNoLogAsync function is used in many places redundantly when the logging version could do the same thing but not log it with an optional bool switch so refactor that shit
|
||||
TODO: REFACTOR biz objects have two creates, an async and sync one, WTF is that about? See if can make it just one async version.
|
||||
- https://docs.microsoft.com/en-us/aspnet/core/performance/performance-best-practices?view=aspnetcore-3.1
|
||||
|
||||
TODO: Need route to gather all object role rights in a format useful to display in UI so that a biz manager can see at a glance the rights for different roles to objects
|
||||
- This way it's dynamic and picked up from the code itself which is always the source of truth so no need to put in the manual
|
||||
- Would likely want to display multiple ways: for a specific object or role or selected user maybe too in the user info form ("effective roles")
|
||||
- Move this over to client once the backend supports it
|
||||
|
||||
TODO: REFACTOR GetNoLogAsync function is used in many places redundantly when the logging version could do the same thing but not log it with an optional bool switch so refactor that shit
|
||||
TODO: REFACTOR biz objects have two creates, an async and sync one, WTF is that about? See if can make it just one async version.
|
||||
|
||||
|
||||
UPDATE SPEC DOCS with new format and names etc or at least remove nonsense as necessary
|
||||
|
||||
UPDATE MANUAL API REGARDING LISTS
|
||||
|
||||
TODO: DataFilter how to distinguish between filtering on specific ID value or on value column
|
||||
- Might need to add a filter on ID type of thing maybe?
|
||||
|
||||
@@ -230,7 +230,7 @@ namespace AyaNova.Api.Controllers
|
||||
});
|
||||
|
||||
//EVENT LOG
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, attachToObject.ObjectId, attachToObject.ObjectType, AyaEvent.AttachmentCreate, v.DisplayFileName), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, attachToObject.ObjectId, attachToObject.ObjectType, AyaEvent.AttachmentCreate, v.DisplayFileName), ct);
|
||||
|
||||
//SEARCH INDEXING
|
||||
// Search.ProcessNewObjectKeywords( UserLocaleIdFromContext.Id(HttpContext.Items), v.Id, AyaType.FileAttachment, v.DisplayFileName, v.DisplayFileName, v.Notes, v.StoredFileName);
|
||||
@@ -303,7 +303,7 @@ namespace AyaNova.Api.Controllers
|
||||
FileUtil.deleteFileAttachment(dbObj, ct);
|
||||
|
||||
//Event log process delete
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDelete, dbObj.DisplayFileName), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDelete, dbObj.DisplayFileName), ct);
|
||||
|
||||
//Delete search index
|
||||
Search.ProcessDeletedObjectKeywords(dbObj.Id, AyaType.FileAttachment);
|
||||
@@ -385,7 +385,7 @@ namespace AyaNova.Api.Controllers
|
||||
}
|
||||
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDownload, dbObj.DisplayFileName), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDownload, dbObj.DisplayFileName), ct);
|
||||
|
||||
return PhysicalFile(filePath, mimetype, dbObj.DisplayFileName);
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace AyaNova.Api.Controllers
|
||||
}
|
||||
var ret = AyaNova.Core.License.LicenseInfoAsJson;
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseFetch), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseFetch), ct);
|
||||
|
||||
return Ok(ApiOkResponse.Response(ret, true));
|
||||
}
|
||||
@@ -169,7 +169,7 @@ namespace AyaNova.Api.Controllers
|
||||
var ret = Core.License.RequestTrial(requestData.EmailAddress, requestData.RegisteredTo, log);
|
||||
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseTrialRequest), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseTrialRequest), ct);
|
||||
|
||||
return Ok(ApiOkResponse.Response(ret, true));
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ namespace AyaNova.Api.Controllers
|
||||
return BadRequest(new ApiErrorResponse(biz.Errors));
|
||||
}
|
||||
//Log
|
||||
EventLogProcessor.DeleteObject(biz.UserId, AyaType.Locale, dbObj.Id, dbObj.Name, ct);
|
||||
EventLogProcessor.DeleteObjectLogAsync(biz.UserId, AyaType.Locale, dbObj.Id, dbObj.Name, ct);
|
||||
await ct.SaveChangesAsync();
|
||||
|
||||
//Delete children / attached objects
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace AyaNova.Api.Controllers
|
||||
string sResult = await GetTheMetrics("plain");
|
||||
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
|
||||
|
||||
return Content(sResult);
|
||||
}
|
||||
@@ -94,7 +94,7 @@ namespace AyaNova.Api.Controllers
|
||||
JObject json = JObject.Parse(sResult);
|
||||
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
|
||||
|
||||
return Ok(ApiOkResponse.Response(json, true));
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace AyaNova.Api.Controllers
|
||||
serverState.SetState(desiredState, state.Reason);
|
||||
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.ServerState, AyaEvent.ServerStateChange, $"{state.ServerState}-{state.Reason}"), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.ServerState, AyaEvent.ServerStateChange, $"{state.ServerState}-{state.Reason}"), ct);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace AyaNova.Api.Controllers
|
||||
return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
|
||||
}
|
||||
|
||||
return Ok(ApiOkResponse.Response(TagUtil.PickListFiltered(ct, query),true));
|
||||
return Ok(ApiOkResponse.Response(TagUtil.PickListFilteredAsync(ct, query),true));
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace AyaNova.Api.Controllers
|
||||
return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
|
||||
}
|
||||
|
||||
return Ok(ApiOkResponse.Response(TagUtil.CloudListFiltered(ct, query), true));
|
||||
return Ok(ApiOkResponse.Response(TagUtil.CloudListFilteredAsync(ct, query), true));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace AyaNova.Api.Controllers
|
||||
JobsBiz.AddJob(j, ct);
|
||||
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.TrialSeeder, AyaEvent.Created, size), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.TrialSeeder, AyaEvent.Created, size), ct);
|
||||
|
||||
return Accepted(new { JobId = j.GId });//202 accepted
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace AyaNova.Biz
|
||||
//Handle child and associated items:
|
||||
|
||||
//EVENT LOG
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
|
||||
|
||||
//SEARCH INDEXING
|
||||
// Search.ProcessNewObjectKeywords(UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.Name);
|
||||
@@ -95,7 +95,7 @@ namespace AyaNova.Biz
|
||||
//Handle child and associated items:
|
||||
|
||||
//EVENT LOG
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), TempContext);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), TempContext);
|
||||
|
||||
//SEARCH INDEXING
|
||||
// Search.ProcessNewObjectKeywords(UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.Name);
|
||||
@@ -116,7 +116,7 @@ namespace AyaNova.Biz
|
||||
if (ret != null)
|
||||
{
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -175,7 +175,7 @@ namespace AyaNova.Biz
|
||||
return false;
|
||||
|
||||
//Log modification and save context
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
|
||||
//Update keywords
|
||||
// Search.ProcessUpdatedObjectKeywords(UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Name);
|
||||
@@ -201,7 +201,7 @@ namespace AyaNova.Biz
|
||||
//Delete sibling objects
|
||||
|
||||
//Event log process delete
|
||||
EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct);
|
||||
EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct);
|
||||
ct.SaveChanges();
|
||||
|
||||
//Delete search index
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace AyaNova.Biz
|
||||
if (log)
|
||||
{
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, ret.Id, BizType, AyaEvent.Retrieved), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, ret.Id, BizType, AyaEvent.Retrieved), ct);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ namespace AyaNova.Biz
|
||||
return false;
|
||||
|
||||
//Log modification and save context
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ namespace AyaNova.Biz
|
||||
ct.DataListTemplate.Remove(dbObj);
|
||||
ct.SaveChanges();
|
||||
//Event log process delete
|
||||
EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.DataListKey, ct);
|
||||
EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.DataListKey, ct);
|
||||
ct.SaveChanges();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using AyaNova.Models;
|
||||
using AyaNova.Util;
|
||||
|
||||
|
||||
namespace AyaNova.Biz
|
||||
@@ -21,10 +16,10 @@ namespace AyaNova.Biz
|
||||
/// <param name="newEvent"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
internal static void LogEventToDatabaseAndSaveEntireContext(Event newEvent, AyContext ct)
|
||||
internal static async Task LogEventToDatabaseAsync(Event newEvent, AyContext ct)
|
||||
{
|
||||
ct.Event.Add(newEvent);
|
||||
ct.SaveChanges();
|
||||
await ct.Event.AddAsync(newEvent);
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,10 +33,11 @@ namespace AyaNova.Biz
|
||||
/// <param name="ayId"></param>
|
||||
/// <param name="textra"></param>
|
||||
/// <param name="ct"></param>
|
||||
internal static void DeleteObject(long userId, AyaType ayType, long ayId, string textra, AyContext ct)
|
||||
internal static async Task DeleteObjectLogAsync(long userId, AyaType ayType, long ayId, string textra, AyContext ct)
|
||||
{
|
||||
ct.Database.ExecuteSqlInterpolated($"delete from aevent where aytype = {ayType} and ayid={ayId}");
|
||||
ct.Event.Add(new Event(userId, ayId, ayType, AyaEvent.Deleted, textra));
|
||||
await ct.Database.ExecuteSqlInterpolatedAsync($"delete from aevent where aytype = {ayType} and ayid={ayId}");
|
||||
await ct.Event.AddAsync(new Event(userId, ayId, ayType, AyaEvent.Deleted, textra));
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -53,7 +49,7 @@ namespace AyaNova.Biz
|
||||
//This is also an example of conditional where statements
|
||||
|
||||
//Set up the query
|
||||
var q = ct.Event.Select(m => m);
|
||||
var q = ct.Event.Select(m => m).AsNoTracking();
|
||||
|
||||
q = q.Where(m => m.AyId == opt.AyId);
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace AyaNova.Biz
|
||||
//Handle child and associated items:
|
||||
|
||||
//EVENT LOG
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
|
||||
|
||||
//SEARCH INDEXING
|
||||
// Search.ProcessNewObjectKeywords(UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.Name);
|
||||
@@ -141,7 +141,7 @@ namespace AyaNova.Biz
|
||||
dbObj.Template = JsonUtil.CompactJson(dbObj.Template);
|
||||
|
||||
//Log modification and save context
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
|
||||
//Update keywords
|
||||
// Search.ProcessUpdatedObjectKeywords(UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Name);
|
||||
|
||||
@@ -349,9 +349,9 @@ namespace AyaNova.Biz
|
||||
|
||||
//handle EventLog entries for users now that we have the user's created
|
||||
//Created
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(Creator, RavenId, ayaType, AyaEvent.Created, Created), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(Creator, RavenId, ayaType, AyaEvent.Created, Created), ct);
|
||||
//MODIFIED
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(Modifier, RavenId, ayaType, AyaEvent.Modified, Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(Modifier, RavenId, ayaType, AyaEvent.Modified, Modified), ct);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace AyaNova.Biz
|
||||
ct.Locale.Add(NewLocale);
|
||||
await ct.SaveChangesAsync();
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, NewLocale.Id, AyaType.Locale, AyaEvent.Created), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, NewLocale.Id, AyaType.Locale, AyaEvent.Created), ct);
|
||||
return NewLocale;
|
||||
|
||||
}
|
||||
@@ -242,7 +242,7 @@ namespace AyaNova.Biz
|
||||
ct.SaveChanges();
|
||||
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbParent.Id, AyaType.Locale, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbParent.Id, AyaType.Locale, AyaEvent.Modified), ct);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -269,7 +269,7 @@ namespace AyaNova.Biz
|
||||
|
||||
ct.SaveChanges();
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, AyaType.Locale, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, AyaType.Locale, AyaEvent.Modified), ct);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -611,7 +611,7 @@ namespace AyaNova.Biz
|
||||
ct.SaveChanges();
|
||||
|
||||
//Log now that we have the Id, note that there is no source created / modified for this so just attributing to current userId
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, l.Id, AyaType.Locale, AyaEvent.Created), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, l.Id, AyaType.Locale, AyaEvent.Created), ct);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -4,6 +4,7 @@ using AyaNova.Util;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using AyaNova.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AyaNova.Biz
|
||||
{
|
||||
@@ -42,7 +43,7 @@ namespace AyaNova.Biz
|
||||
|
||||
|
||||
|
||||
public static void ProcessDeleteTagsInRepository(AyContext ct, List<string> deleteTags)
|
||||
public static async Task ProcessDeleteTagsInRepositoryAsync(AyContext ct, List<string> deleteTags)
|
||||
{
|
||||
if (deleteTags.Count == 0) return;
|
||||
foreach (string s in deleteTags)
|
||||
@@ -55,7 +56,7 @@ namespace AyaNova.Biz
|
||||
do
|
||||
{
|
||||
//START: Get tag word and concurrency token and count
|
||||
var ExistingTag = ct.Tag.FirstOrDefault(x => x.Name == s);
|
||||
var ExistingTag = await ct.Tag.FirstOrDefaultAsync(x => x.Name == s);
|
||||
//if not present, then nothing to do
|
||||
if (ExistingTag != null)
|
||||
{
|
||||
@@ -73,7 +74,7 @@ namespace AyaNova.Biz
|
||||
|
||||
try
|
||||
{
|
||||
ct.SaveChanges();
|
||||
await ct.SaveChangesAsync();
|
||||
bDone = true;
|
||||
}
|
||||
catch (Exception ex) when (ex is DbUpdateConcurrencyException)//allow for possible other types
|
||||
@@ -86,7 +87,7 @@ namespace AyaNova.Biz
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessUpdateTagsInRepository(AyContext ct, List<string> newTags, List<string> originalTags = null)
|
||||
public static async Task ProcessUpdateTagsInRepositoryAsync(AyContext ct, List<string> newTags, List<string> originalTags = null)
|
||||
{
|
||||
//just in case no new tags are present which could mean a user removed all tags from a record so this
|
||||
//needs to proceed with the code below even if newTags is null as long as originalTags isn't also null
|
||||
@@ -124,11 +125,11 @@ namespace AyaNova.Biz
|
||||
do
|
||||
{
|
||||
//START: Get tag word and concurrency token and count
|
||||
var ExistingTag = ct.Tag.FirstOrDefault(x => x.Name == s);
|
||||
var ExistingTag = await ct.Tag.FirstOrDefaultAsync(x => x.Name == s);
|
||||
//if not present, then add it with a count of 0
|
||||
if (ExistingTag == null)
|
||||
{
|
||||
ct.Tag.Add(new Tag() { Name = s, RefCount = 1 });
|
||||
await ct.Tag.AddAsync(new Tag() { Name = s, RefCount = 1 });
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -137,7 +138,7 @@ namespace AyaNova.Biz
|
||||
}
|
||||
try
|
||||
{
|
||||
ct.SaveChanges();
|
||||
await ct.SaveChangesAsync();
|
||||
bDone = true;
|
||||
}
|
||||
catch (Exception ex) when (ex is DbUpdateConcurrencyException)//this allows for other types
|
||||
@@ -149,43 +150,57 @@ namespace AyaNova.Biz
|
||||
}
|
||||
|
||||
//DELETE TAGS
|
||||
ProcessDeleteTagsInRepository(ct, deleteTags);
|
||||
await ProcessDeleteTagsInRepositoryAsync(ct, deleteTags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Pick list for driving pick list route
|
||||
//going with contains for now as I think it's more useful in the long run and still captures startswith intent by user
|
||||
public static List<string> PickListFiltered(AyContext ct, string q)
|
||||
public static async Task<List<string>> PickListFilteredAsync(AyContext ct, string q)
|
||||
{
|
||||
//This path is intended for internal use and accepts that there may not be a filter specified
|
||||
//however the client will always require a filter to display a tag list for choosing from
|
||||
if (string.IsNullOrWhiteSpace(q))
|
||||
{
|
||||
return ct.Tag.OrderBy(x => x.Name).Select(x => x.Name).ToList();
|
||||
return await ct.Tag.OrderBy(x => x.Name)
|
||||
.Select(x => x.Name)
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
q = NormalizeTag(q);
|
||||
return ct.Tag.Where(x => x.Name.Contains(q)).OrderBy(x => x.Name).Select(x => x.Name).Take(25).ToList();
|
||||
return await ct.Tag
|
||||
.Where(x => x.Name.Contains(q))
|
||||
.OrderBy(x => x.Name)
|
||||
.Select(x => x.Name)
|
||||
.Take(25)
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
//Cloud list
|
||||
public static List<TagCloudItem> CloudListFiltered(AyContext ct, string q)
|
||||
public static async Task<List<TagCloudItem>> CloudListFilteredAsync(AyContext ct, string q)
|
||||
{
|
||||
//This path is intended for internal use and accepts that there may not be a filter specified
|
||||
//however the client will always require a filter to display a tag list for choosing from
|
||||
if (string.IsNullOrWhiteSpace(q))
|
||||
{
|
||||
return ct.Tag.OrderByDescending(x => x.RefCount).Select(x => new TagCloudItem() { Name = x.Name, RefCount = x.RefCount }).ToList();
|
||||
return await ct.Tag.OrderByDescending(x => x.RefCount).Select(x => new TagCloudItem() { Name = x.Name, RefCount = x.RefCount }).AsNoTracking().ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
q = NormalizeTag(q);
|
||||
//TODO: Use the EF CORE TAKE method to restrict the results to a maximum limit
|
||||
//however need to ensure it doesn't balk when the limit is higher than the number of results (probably not but test that)
|
||||
return ct.Tag.Where(x => x.Name.Contains(q)).OrderByDescending(x => x.RefCount).Select(x => new TagCloudItem() { Name = x.Name, RefCount = x.RefCount }).ToList();
|
||||
return await ct.Tag
|
||||
.Where(x => x.Name.Contains(q))
|
||||
.OrderByDescending(x => x.RefCount)
|
||||
.Select(x => new TagCloudItem() { Name = x.Name, RefCount = x.RefCount })
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,13 +81,13 @@ namespace AyaNova.Biz
|
||||
//Handle child and associated items
|
||||
|
||||
//Log event
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, inObj.Id, BizType, AyaEvent.Created), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, inObj.Id, BizType, AyaEvent.Created), ct);
|
||||
|
||||
//SEARCH INDEXING
|
||||
SearchIndex(inObj, true);
|
||||
|
||||
//TAGS
|
||||
TagUtil.ProcessUpdateTagsInRepository(ct, inObj.Tags, null);
|
||||
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, inObj.Tags, null);
|
||||
|
||||
return inObj;
|
||||
|
||||
@@ -123,13 +123,13 @@ namespace AyaNova.Biz
|
||||
//Handle child and associated items
|
||||
|
||||
//Log event
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, inObj.Id, BizType, AyaEvent.Created), TempContext);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, inObj.Id, BizType, AyaEvent.Created), TempContext);
|
||||
|
||||
//SEARCH INDEXING
|
||||
SearchIndex(inObj, true);
|
||||
|
||||
//TAGS
|
||||
TagUtil.ProcessUpdateTagsInRepository(TempContext, inObj.Tags, null);
|
||||
TagUtil.ProcessUpdateTagsInRepositoryAsync(TempContext, inObj.Tags, null);
|
||||
|
||||
return inObj;
|
||||
|
||||
@@ -147,7 +147,7 @@ namespace AyaNova.Biz
|
||||
if (ret != null)
|
||||
{
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -302,11 +302,11 @@ namespace AyaNova.Biz
|
||||
|
||||
|
||||
//Log modification and save context
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
|
||||
SearchIndex(dbObj, false);
|
||||
|
||||
TagUtil.ProcessUpdateTagsInRepository(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
|
||||
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -339,10 +339,10 @@ namespace AyaNova.Biz
|
||||
return false;
|
||||
|
||||
//Log modification and save context
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
SearchIndex(dbObj, false);
|
||||
|
||||
TagUtil.ProcessUpdateTagsInRepository(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
|
||||
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -379,10 +379,10 @@ namespace AyaNova.Biz
|
||||
ct.Database.ExecuteSqlInterpolated($"delete from auseroptions where userid={dbObj.Id}");
|
||||
|
||||
|
||||
EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct);
|
||||
EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct);
|
||||
ct.SaveChanges();
|
||||
Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType);
|
||||
TagUtil.ProcessDeleteTagsInRepository(ct, dbObj.Tags);
|
||||
TagUtil.ProcessDeleteTagsInRepositoryAsync(ct, dbObj.Tags);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace AyaNova.Biz
|
||||
|
||||
ct.SaveChanges();
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, AyaType.UserOptions, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, AyaType.UserOptions, AyaEvent.Modified), ct);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace AyaNova.Biz
|
||||
|
||||
ct.SaveChanges();
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, AyaType.UserOptions, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, AyaType.UserOptions, AyaEvent.Modified), ct);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace AyaNova.Biz
|
||||
if (log && ret != null)
|
||||
{
|
||||
//Log
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ namespace AyaNova.Biz
|
||||
//CREATE
|
||||
|
||||
//Called from route and also seeder
|
||||
internal Widget Create(Widget inObj)
|
||||
internal async Task<Widget> CreateAsync(Widget inObj)
|
||||
{
|
||||
Validate(inObj, null);
|
||||
if (HasErrors)
|
||||
@@ -81,57 +81,20 @@ namespace AyaNova.Biz
|
||||
|
||||
outObj.Tags = TagUtil.NormalizeTags(outObj.Tags);
|
||||
outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
|
||||
|
||||
//Save to db
|
||||
|
||||
//add syncronously and don't save but let the log save
|
||||
//THIS SAVED 1 SECOND OUT OF 22 for seeding 500 widgets
|
||||
ct.Widget.Add(outObj);
|
||||
|
||||
//Save to db
|
||||
await ct.Widget.AddAsync(outObj);
|
||||
await ct.SaveChangesAsync();
|
||||
//Handle child and associated items:
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
|
||||
|
||||
|
||||
//This takes 16 seconds out of 22 when seeding 500 widgets
|
||||
SearchIndex(outObj, true);
|
||||
|
||||
|
||||
//This takes 2 seconds out of 22 when seeding 500 widgets
|
||||
TagUtil.ProcessUpdateTagsInRepository(ct, outObj.Tags, null);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
|
||||
SearchIndex(outObj, true);
|
||||
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, outObj.Tags, null);
|
||||
|
||||
return outObj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// //Internal version for seeding
|
||||
// internal Widget Create(AyContext TempContext, Widget inObj)
|
||||
// {
|
||||
// Validate(inObj, null);
|
||||
// if (HasErrors)
|
||||
// return null;
|
||||
// else
|
||||
// {
|
||||
// //do stuff with widget
|
||||
// Widget outObj = inObj;
|
||||
|
||||
// //Test get serial id visible id number from generator
|
||||
// outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext();
|
||||
// outObj.Tags = TagUtil.NormalizeTags(outObj.Tags);
|
||||
// outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
|
||||
|
||||
// TempContext.Widget.Add(outObj);
|
||||
// TempContext.SaveChanges();
|
||||
|
||||
// //Handle child and associated items:
|
||||
// EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), TempContext);
|
||||
// SearchIndex(outObj, true);
|
||||
// TagUtil.ProcessUpdateTagsInRepository(TempContext, outObj.Tags, null);
|
||||
|
||||
// return outObj;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DUPLICATE
|
||||
@@ -153,9 +116,9 @@ namespace AyaNova.Biz
|
||||
await ct.SaveChangesAsync();
|
||||
|
||||
//Handle child and associated items:
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
|
||||
SearchIndex(outObj, true);
|
||||
TagUtil.ProcessUpdateTagsInRepository(ct, outObj.Tags, null);
|
||||
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, outObj.Tags, null);
|
||||
return outObj;
|
||||
|
||||
}
|
||||
@@ -188,9 +151,9 @@ namespace AyaNova.Biz
|
||||
return false;
|
||||
|
||||
//Log event and save context
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
SearchIndex(dbObj, false);
|
||||
TagUtil.ProcessUpdateTagsInRepository(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
|
||||
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -218,10 +181,10 @@ namespace AyaNova.Biz
|
||||
return false;
|
||||
|
||||
//Log event and save context
|
||||
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
|
||||
SearchIndex(dbObj, false);
|
||||
|
||||
TagUtil.ProcessUpdateTagsInRepository(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
|
||||
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -256,10 +219,10 @@ namespace AyaNova.Biz
|
||||
ct.SaveChanges();
|
||||
|
||||
//Log event and save context
|
||||
EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct);
|
||||
EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct);
|
||||
ct.SaveChanges();
|
||||
Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType);
|
||||
TagUtil.ProcessDeleteTagsInRepository(ct, dbObj.Tags);
|
||||
TagUtil.ProcessDeleteTagsInRepositoryAsync(ct, dbObj.Tags);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -399,6 +399,8 @@ namespace AyaNova.Util
|
||||
}
|
||||
finally
|
||||
{
|
||||
//TODO: fully async: watch the job and don't turn the state back until the job is done?
|
||||
|
||||
log.LogInformation($"Seeder: setting server state back to {wasServerState.ToString()}");
|
||||
apiServerState.SetState(wasServerState, wasReason);
|
||||
}
|
||||
@@ -570,22 +572,6 @@ namespace AyaNova.Util
|
||||
//
|
||||
public static void GenSeedWidget(ILogger log, int count)
|
||||
{
|
||||
//COMMIT BEFORE GOING NON ASYNC AGAIN TO SEE IF MEDIUM 500 WIDGETS STILL TAKES SO LONG:
|
||||
//ASYNC CACHED STUFF 2020-01-23 15:58:31.1619|INFO|Seeder|500 Widgets seeded in 54890 ms
|
||||
//NON ASYNC ORIGINAL METHOD 2020-01-23 16:19:59.9131|INFO|Seeder|500 Widgets seeded in 51442 ms
|
||||
//NON ASYNC HERE BUT CALLING ASYNC CREATE IN WIDGET: 2020-01-23 16:23:58.9478|INFO|Seeder|500 Widgets seeded in 53362 ms
|
||||
//NOT CALLING SAVE ON WIDGET BUT DOING ALL OTHER CODE: 2020-01-23 16:25:45.0293|INFO|Seeder|500 Widgets seeded in 30 ms
|
||||
//So slowness is all in the save code, let's see whats what there...
|
||||
// first tried not caching teh widgetbiz object: 2020-01-23 16:28:58.0876|INFO|Seeder|500 Widgets seeded in 53577 ms
|
||||
//so that's pointless to cache it
|
||||
//ONE LAST THING IN HERE, trying *NOT* caching the db context and create each time: 2020-01-23 16:32:13.8966|INFO|Seeder|500 Widgets seeded in 22679 ms
|
||||
// - Holy shit, that's back to where it was a few days ago, so for some reason using the same context over and over is slowing shit down drastically
|
||||
// ripping that out now.
|
||||
|
||||
//OK, making changes in CREATE code in widgetbiz
|
||||
//First removed extra save call and async db access shaved off a second
|
||||
//the commented out the Search indexer and it dropped from 22 seconds to 4.5!!!!
|
||||
//So the search indexing code is super fucking slow 2020-01-23 16:45:20.9518|INFO|Seeder|500 Widgets seeded in 4572 ms
|
||||
|
||||
var f = new Bogus.Faker();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user