You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
6.9 KiB
C#

using System;
using Enyim.Caching;
using Expedience.Infrastructure.Models;
using Expedience.Models;
using Microsoft.EntityFrameworkCore;
namespace Expedience.Infrastructure;
public interface IExpedienceRepository
{
ValueTask<List<DutyCompletionRecord>> GetDutyCompletionRecords(string expac, CancellationToken cancellationToken);
ValueTask<List<DeepDungeonRecord>> GetDeepDungeonRecords(CancellationToken cancellationToken);
ValueTask<List<ContentTypeRecord>> GetContentTypeRecords(string contentType, CancellationToken cancellationToken);
ValueTask<List<TopXCompletionResultDto>> GetTopXRecords(int recordType, int territoryId, int limit, CancellationToken cancellationToken);
}
public class ExpedienceRepository : IExpedienceRepository
{
private readonly ExpedienceContext _dbContext;
private readonly IMemcachedClient _memcachedClient;
public ExpedienceRepository(ExpedienceContext dbContext, IMemcachedClient memcachedClient)
{
_dbContext = dbContext;
_memcachedClient = memcachedClient;
}
public async ValueTask<List<DutyCompletionRecord>> GetDutyCompletionRecords(string expac, CancellationToken cancellationToken)
{
var cacheKey = $"xpd-dcr-{expac}";
var cacheSeconds = 600;
var records = await _memcachedClient.GetValueOrCreateAsync(cacheKey, cacheSeconds,
async () => await _dbContext.DutyCompletionRecords.FromSqlInterpolated($"SELECT * FROM public.get_dutycompletionrecords({expac})")
.ToListAsync(cancellationToken));
return records;
}
public async ValueTask<List<DeepDungeonRecord>> GetDeepDungeonRecords(CancellationToken cancellationToken)
{
var cacheKey = $"xpd-dd";
var cacheSeconds = 600;
var records = await _memcachedClient.GetValueOrCreateAsync(cacheKey, cacheSeconds,
async () => await _dbContext.DeepDungeonRecords.FromSqlInterpolated($"SELECT * FROM public.get_deepdungeonresults()")
.ToListAsync(cancellationToken));
return records;
}
public async ValueTask<List<TopXCompletionResultDto>> GetTopXRecords(int recordType, int territoryId, int limit, CancellationToken cancellationToken)
{
var cacheKey = $"xpd-topx-{recordType}-{territoryId}-{limit}";
var cacheSeconds = 600;
var records = await _memcachedClient.GetValueOrCreateAsync(cacheKey, cacheSeconds,
async () =>
{
var topXResults = await _dbContext.TopXRecords.FromSqlInterpolated($"SELECT * FROM public.get_topxcompletionresults({recordType}, {territoryId}, {limit})")
.ToListAsync(cancellationToken);
if (topXResults.Count == 0) return new List<TopXCompletionResultDto>();
var topXIds = topXResults.Select(r => r.Id).ToList();
var userIds = topXResults.Select(r => r.UserId).Distinct().ToList();
var dutyCompletionResults = await _dbContext.DutyCompletionResults
.Where(dcr => topXIds.Contains(dcr.Id))
.ToListAsync();
var dutyMembers = await _dbContext.DutyMembers
.Where(dm => topXIds.Contains(dm.UploadId))
.ToListAsync();
var users = await _dbContext.Users
.Where(u => userIds.Contains(u.UserId))
.ToListAsync();
var territory = await _dbContext.Territories
.FirstAsync(t => t.TerritoryId == territoryId);
var territoryDto = new TerritoryDto
{
TerritoryId = territory.TerritoryId,
PlaceName = territory.PlaceName,
ContentName = territory.ContentName,
Level = territory.Level,
ContentType = territory.ContentType,
Expac = territory.Expac
};
var resultDtos = topXResults.Select(result => new TopXCompletionResultDto
{
Rank = result.Rank,
Duration = result.Duration,
DutyCompletionResult = dutyCompletionResults
.Where(dcr => dcr.Id == result.Id)
.Select(dcr => new DutyCompletionResultDto
{
Id = dcr.Id,
UserId = dcr.UserId,
TerritoryId = dcr.TerritoryId,
HasEcho = dcr.HasEcho,
IsUnrestricted = dcr.IsUnrestricted,
IsMinILevel = dcr.IsMinILevel,
HasNpcMembers = dcr.HasNpcMembers,
StartTime = dcr.StartTime,
EndTime = dcr.EndTime,
Hours = dcr.Hours,
Minutes = dcr.Minutes,
Seconds = dcr.Seconds,
Milliseconds = dcr.Milliseconds,
GameVersion = dcr.GameVersion,
PluginVersion = dcr.PluginVersion,
Lang = dcr.Lang,
DataCenter = dcr.DataCenter,
UploadedAt = dcr.UploadedAt
}).First(),
DutyMembers = dutyMembers
.Where(dm => dm.UploadId == result.Id)
.Select(dm => new DutyMemberDto
{
UploadId = dm.UploadId,
GroupNumber = dm.GroupNumber,
MemberNumber = dm.MemberNumber,
Level = dm.Level,
ClassJob = dm.ClassJob,
IsNpc = dm.IsNpc,
IsPlayer = dm.IsPlayer,
}).ToList(),
User = users
.Where(u => u.UserId == result.UserId)
.Select(u => new UserDto
{
UserId = u.UserId,
UserName = u.UserName,
WorldId = u.WorldId
}).FirstOrDefault(),
Territory = territoryDto
}).ToList();
return resultDtos;
});
return records;
}
public async ValueTask<List<ContentTypeRecord>> GetContentTypeRecords(string contentType, CancellationToken cancellationToken)
{
var cacheKey = $"xpd-th";
var cacheSeconds = 600;
var records = await _memcachedClient.GetValueOrCreateAsync(cacheKey, cacheSeconds,
async () => await _dbContext.ContentTypeRecords.FromSqlInterpolated($"SELECT * FROM public.get_contenttyperesults({contentType})")
.ToListAsync(cancellationToken));
return records;
}
}