2019-02-22 20:06:51 -05:00
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
using SharedLibraryCore.Database;
|
|
|
|
|
using SharedLibraryCore.Database.Models;
|
|
|
|
|
using SharedLibraryCore.Dtos;
|
2018-02-14 14:01:26 -05:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2019-02-22 20:06:51 -05:00
|
|
|
|
using System.Linq;
|
2018-02-14 14:01:26 -05:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
2018-04-08 02:44:42 -04:00
|
|
|
|
namespace SharedLibraryCore.Services
|
2018-02-14 14:01:26 -05:00
|
|
|
|
{
|
|
|
|
|
public class MetaService
|
|
|
|
|
{
|
2019-03-29 22:56:56 -04:00
|
|
|
|
private static List<Func<int, int, int, DateTime?, Task<List<ProfileMeta>>>> _metaActions = new List<Func<int, int, int, DateTime?, Task<List<ProfileMeta>>>>();
|
2018-02-14 14:01:26 -05:00
|
|
|
|
|
2019-02-24 20:07:56 -05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// adds or updates meta key and value to the database
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="metaKey">key of meta data</param>
|
|
|
|
|
/// <param name="metaValue">value of the meta data</param>
|
|
|
|
|
/// <param name="client">client to save the meta for</param>
|
|
|
|
|
/// <returns></returns>
|
2019-02-22 20:06:51 -05:00
|
|
|
|
public async Task AddPersistentMeta(string metaKey, string metaValue, EFClient client)
|
2018-02-14 14:01:26 -05:00
|
|
|
|
{
|
2019-04-08 21:31:32 -04:00
|
|
|
|
// this seems to happen if the client disconnects before they've had time to authenticate and be added
|
|
|
|
|
if (client.ClientId < 1)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-22 20:06:51 -05:00
|
|
|
|
using (var ctx = new DatabaseContext())
|
|
|
|
|
{
|
2019-02-24 20:07:56 -05:00
|
|
|
|
var existingMeta = await ctx.EFMeta
|
|
|
|
|
.Where(_meta => _meta.Key == metaKey)
|
|
|
|
|
.Where(_meta => _meta.ClientId == client.ClientId)
|
|
|
|
|
.FirstOrDefaultAsync();
|
2019-02-22 20:06:51 -05:00
|
|
|
|
|
|
|
|
|
if (existingMeta != null)
|
|
|
|
|
{
|
|
|
|
|
existingMeta.Value = metaValue;
|
|
|
|
|
existingMeta.Updated = DateTime.UtcNow;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ctx.EFMeta.Add(new EFMeta()
|
|
|
|
|
{
|
|
|
|
|
ClientId = client.ClientId,
|
|
|
|
|
Created = DateTime.UtcNow,
|
|
|
|
|
Key = metaKey,
|
|
|
|
|
Value = metaValue
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await ctx.SaveChangesAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-09 10:50:58 -04:00
|
|
|
|
internal static void Clear()
|
|
|
|
|
{
|
|
|
|
|
_metaActions.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-24 20:07:56 -05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// retrieves meta data for given client and key
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="metaKey">key to retrieve value for</param>
|
|
|
|
|
/// <param name="client">client to retrieve meta for</param>
|
|
|
|
|
/// <returns></returns>
|
2019-02-22 20:37:53 -05:00
|
|
|
|
public async Task<EFMeta> GetPersistentMeta(string metaKey, EFClient client)
|
2019-02-22 20:06:51 -05:00
|
|
|
|
{
|
2019-03-09 11:28:04 -05:00
|
|
|
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
2019-02-22 20:06:51 -05:00
|
|
|
|
{
|
2019-02-22 20:37:53 -05:00
|
|
|
|
return await ctx.EFMeta
|
2019-02-22 20:06:51 -05:00
|
|
|
|
.Where(_meta => _meta.Key == metaKey)
|
|
|
|
|
.Where(_meta => _meta.ClientId == client.ClientId)
|
|
|
|
|
.FirstOrDefaultAsync();
|
|
|
|
|
}
|
2018-02-14 14:01:26 -05:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-24 20:07:56 -05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// aads a meta task to the runtime meta list
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="metaAction"></param>
|
2019-03-29 22:56:56 -04:00
|
|
|
|
public static void AddRuntimeMeta(Func<int, int, int, DateTime?, Task<List<ProfileMeta>>> metaAction)
|
2019-02-22 20:06:51 -05:00
|
|
|
|
{
|
|
|
|
|
_metaActions.Add(metaAction);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-24 20:07:56 -05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// retrieves all the runtime meta information for given client idea
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="clientId">id of the client</param>
|
2019-03-27 20:40:26 -04:00
|
|
|
|
/// <param name="count">number of meta items to retrieve</param>
|
|
|
|
|
/// <param name="offset">offset from the first item</param>
|
2019-02-24 20:07:56 -05:00
|
|
|
|
/// <returns></returns>
|
2019-03-29 22:56:56 -04:00
|
|
|
|
public static async Task<List<ProfileMeta>> GetRuntimeMeta(int clientId, int offset = 0, int count = int.MaxValue, DateTime? startAt = null)
|
2018-02-14 14:01:26 -05:00
|
|
|
|
{
|
|
|
|
|
var meta = new List<ProfileMeta>();
|
2019-02-22 20:06:51 -05:00
|
|
|
|
|
|
|
|
|
foreach (var action in _metaActions)
|
|
|
|
|
{
|
2019-03-29 22:56:56 -04:00
|
|
|
|
var metaItems = await action(clientId, offset, count, startAt);
|
|
|
|
|
meta.AddRange(metaItems);
|
2019-02-22 20:06:51 -05:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-29 22:56:56 -04:00
|
|
|
|
if (count == 1)
|
|
|
|
|
{
|
2019-03-30 18:21:01 -04:00
|
|
|
|
var table = new List<List<ProfileMeta>>();
|
|
|
|
|
var metaWithColumn = meta
|
|
|
|
|
.Where(_meta => _meta.Column != null);
|
|
|
|
|
|
|
|
|
|
var columnGrouping = metaWithColumn
|
|
|
|
|
.GroupBy(_meta => _meta.Column);
|
|
|
|
|
|
|
|
|
|
var metaToSort = meta.Except(metaWithColumn).ToList();
|
|
|
|
|
|
|
|
|
|
foreach (var metaItem in columnGrouping)
|
|
|
|
|
{
|
|
|
|
|
table.Add(new List<ProfileMeta>(metaItem));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (metaToSort.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var sortingMeta = metaToSort.First();
|
|
|
|
|
|
|
|
|
|
int indexOfSmallestColumn()
|
|
|
|
|
{
|
|
|
|
|
int index = 0;
|
|
|
|
|
int smallestColumnSize = int.MaxValue;
|
|
|
|
|
for (int i = 0; i < table.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (table[i].Count < smallestColumnSize)
|
|
|
|
|
{
|
|
|
|
|
smallestColumnSize = table[i].Count;
|
|
|
|
|
index = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int columnIndex = indexOfSmallestColumn();
|
|
|
|
|
|
|
|
|
|
sortingMeta.Column = columnIndex;
|
|
|
|
|
sortingMeta.Order = columnGrouping
|
|
|
|
|
.First(_group => _group.Key == columnIndex)
|
|
|
|
|
.Count();
|
|
|
|
|
|
|
|
|
|
table[columnIndex].Add(sortingMeta);
|
|
|
|
|
|
|
|
|
|
metaToSort.Remove(sortingMeta);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-29 22:56:56 -04:00
|
|
|
|
return meta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return meta.OrderByDescending(_meta => _meta.When)
|
|
|
|
|
.Take(count)
|
|
|
|
|
.ToList();
|
2018-02-14 14:01:26 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|