Updated scanner/upsert logic.
This commit is contained in:
@@ -1,25 +1,240 @@
|
||||
using JSMR.Application.VoiceWorks.Commands.SetFavorite;
|
||||
using JSMR.Application.Scanning.Contracts;
|
||||
using JSMR.Application.VoiceWorks.Commands.SetFavorite;
|
||||
using JSMR.Application.VoiceWorks.Ports;
|
||||
using JSMR.Domain.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace JSMR.Infrastructure.Data.Repositories.VoiceWorks;
|
||||
|
||||
public class VoiceWorkWriter(AppDbContext context) : IVoiceWorkWriter
|
||||
public class VoiceWorkWriter(AppDbContext dbContext) : IVoiceWorkWriter
|
||||
{
|
||||
public async Task<int[]> UpsertAsync(IReadOnlyCollection<VoiceWorkIngest> ingests, CancellationToken cancellationToken)
|
||||
{
|
||||
VoiceWorkUpsertContext upsertContext = await CreateUpsertContextAsync(ingests, cancellationToken);
|
||||
|
||||
foreach (VoiceWorkIngest ingest in ingests)
|
||||
{
|
||||
Upsert(ingest, upsertContext);
|
||||
}
|
||||
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return [.. upsertContext.VoiceWorks.Select(x => x.Value.VoiceWorkId)];
|
||||
}
|
||||
|
||||
private async Task<VoiceWorkUpsertContext> CreateUpsertContextAsync(IReadOnlyCollection<VoiceWorkIngest> ingests, CancellationToken cancellationToken)
|
||||
{
|
||||
string[] makerIds = [.. ingests.Select(i => i.MakerId).Where(s => !string.IsNullOrWhiteSpace(s)).Distinct()];
|
||||
string[] productIds = [.. ingests.Select(i => i.ProductId).Distinct()];
|
||||
string[] tagNames = [.. ingests.SelectMany(i => i.Tags).Distinct()];
|
||||
string[] creatorNames = [.. ingests.SelectMany(i => i.Creators).Distinct()];
|
||||
|
||||
VoiceWorkUpsertContext upsertContext = new(
|
||||
Circles: await dbContext.Circles
|
||||
.Where(c => makerIds.Contains(c.MakerId))
|
||||
.ToDictionaryAsync(c => c.MakerId, cancellationToken),
|
||||
VoiceWorks: await dbContext.VoiceWorks
|
||||
.Where(v => productIds.Contains(v.ProductId))
|
||||
.Include(v => v.VoiceWorkCreators)
|
||||
.Include(v => v.VoiceWorkTags)
|
||||
.ToDictionaryAsync(v => v.ProductId, cancellationToken),
|
||||
Tags: await dbContext.Tags
|
||||
.Where(t => tagNames.Contains(t.Name))
|
||||
.ToDictionaryAsync(t => t.Name, cancellationToken),
|
||||
Creators: await dbContext.Creators
|
||||
.Where(cr => creatorNames.Contains(cr.Name))
|
||||
.ToDictionaryAsync(cr => cr.Name, cancellationToken)
|
||||
);
|
||||
|
||||
return upsertContext;
|
||||
}
|
||||
|
||||
private void Upsert(VoiceWorkIngest ingest, VoiceWorkUpsertContext upsertContext)
|
||||
{
|
||||
UpsertCircle(ingest, upsertContext);
|
||||
UpsertVoiceWork(ingest, upsertContext);
|
||||
UpsertTags(ingest, upsertContext);
|
||||
UpsertVoiceWorkTags(ingest, upsertContext);
|
||||
UpsertCreators(ingest, upsertContext);
|
||||
UpsertVoiceWorkCreators(ingest, upsertContext);
|
||||
}
|
||||
|
||||
private void UpsertCircle(VoiceWorkIngest ingest, VoiceWorkUpsertContext upsertContext)
|
||||
{
|
||||
Circle circle = GetOrAddCircle(ingest, upsertContext);
|
||||
circle.Name = ingest.MakerName;
|
||||
}
|
||||
|
||||
private Circle GetOrAddCircle(VoiceWorkIngest ingest, VoiceWorkUpsertContext upsertContext)
|
||||
{
|
||||
if (!upsertContext.Circles.TryGetValue(ingest.MakerId, out Circle? circle))
|
||||
{
|
||||
circle = new Circle
|
||||
{
|
||||
MakerId = ingest.MakerId,
|
||||
Name = ingest.MakerName,
|
||||
};
|
||||
|
||||
dbContext.Circles.Add(circle);
|
||||
upsertContext.Circles[ingest.MakerId] = circle;
|
||||
}
|
||||
|
||||
return circle;
|
||||
}
|
||||
|
||||
private void UpsertVoiceWork(VoiceWorkIngest ingest, VoiceWorkUpsertContext upsertContext)
|
||||
{
|
||||
VoiceWork voiceWork = GetOrAddVoiceWork(ingest, upsertContext);
|
||||
voiceWork.Circle = upsertContext.Circles[ingest.MakerId];
|
||||
voiceWork.ProductName = ingest.Title;
|
||||
voiceWork.Description = ingest.Description;
|
||||
voiceWork.Downloads = ingest.Downloads;
|
||||
voiceWork.WishlistCount = ingest.WishlistCount;
|
||||
voiceWork.HasTrial = ingest.HasTrial;
|
||||
voiceWork.HasChobit = ingest.HasDLPlay;
|
||||
voiceWork.StarRating = ingest.StarRating;
|
||||
voiceWork.Votes = ingest.Votes;
|
||||
|
||||
voiceWork.IsValid = true;
|
||||
|
||||
//var est = i.EstimatedDate?.ToDateTime(new TimeOnly(0, 0));
|
||||
//if (vw2.ExpectedDate != est) { vw2.ExpectedDate = est; changed = true; }
|
||||
|
||||
//var sales = i.SalesDate?.ToDateTime(new TimeOnly(0, 0));
|
||||
//if (vw2.SalesDate != sales) { vw2.SalesDate = sales; changed = true; }
|
||||
}
|
||||
|
||||
private VoiceWork GetOrAddVoiceWork(VoiceWorkIngest ingest, VoiceWorkUpsertContext upsertContext)
|
||||
{
|
||||
if (!upsertContext.VoiceWorks.TryGetValue(ingest.ProductId, out VoiceWork? voiceWork))
|
||||
{
|
||||
voiceWork = new VoiceWork
|
||||
{
|
||||
ProductId = ingest.ProductId
|
||||
};
|
||||
|
||||
dbContext.VoiceWorks.Add(voiceWork);
|
||||
upsertContext.VoiceWorks[ingest.ProductId] = voiceWork;
|
||||
}
|
||||
|
||||
return voiceWork;
|
||||
}
|
||||
|
||||
private void UpsertTags(VoiceWorkIngest ingest, VoiceWorkUpsertContext upsertContext)
|
||||
{
|
||||
foreach (string tagName in ingest.Tags)
|
||||
{
|
||||
GetOrAddTag(tagName, upsertContext);
|
||||
}
|
||||
}
|
||||
|
||||
private Tag GetOrAddTag(string tagName, VoiceWorkUpsertContext upsertContext)
|
||||
{
|
||||
if (!upsertContext.Tags.TryGetValue(tagName, out Tag? tag))
|
||||
{
|
||||
tag = new Tag
|
||||
{
|
||||
Name = tagName
|
||||
};
|
||||
|
||||
dbContext.Tags.Add(tag);
|
||||
upsertContext.Tags[tagName] = tag;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
private void UpsertCreators(VoiceWorkIngest ingest, VoiceWorkUpsertContext something)
|
||||
{
|
||||
foreach (string creatorName in ingest.Creators)
|
||||
{
|
||||
GetOrAddCreator(creatorName, something);
|
||||
}
|
||||
}
|
||||
|
||||
private Creator GetOrAddCreator(string creatorName, VoiceWorkUpsertContext something)
|
||||
{
|
||||
if (!something.Creators.TryGetValue(creatorName, out Creator? creator))
|
||||
{
|
||||
creator = new Creator
|
||||
{
|
||||
Name = creatorName
|
||||
};
|
||||
|
||||
dbContext.Creators.Add(creator);
|
||||
something.Creators[creatorName] = creator;
|
||||
}
|
||||
|
||||
return creator;
|
||||
}
|
||||
|
||||
private void UpsertVoiceWorkTags(VoiceWorkIngest ingest, VoiceWorkUpsertContext something)
|
||||
{
|
||||
VoiceWork voiceWork = something.VoiceWorks[ingest.ProductId];
|
||||
Dictionary<int, VoiceWorkTag> existingTagLinks = voiceWork.VoiceWorkTags.ToDictionary(x => x.TagId);
|
||||
|
||||
int position = 1;
|
||||
|
||||
foreach (string tagName in ingest.Tags)
|
||||
{
|
||||
Tag tag = something.Tags[tagName];
|
||||
|
||||
if (!existingTagLinks.TryGetValue(tag.TagId, out VoiceWorkTag? voiceWorkTag))
|
||||
{
|
||||
voiceWorkTag = new VoiceWorkTag
|
||||
{
|
||||
VoiceWork = voiceWork,
|
||||
Tag = tag
|
||||
};
|
||||
|
||||
dbContext.VoiceWorkTags.Add(voiceWorkTag);
|
||||
}
|
||||
|
||||
voiceWorkTag.Position = position++;
|
||||
voiceWorkTag.IsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpsertVoiceWorkCreators(VoiceWorkIngest ingest, VoiceWorkUpsertContext something)
|
||||
{
|
||||
VoiceWork voiceWork = something.VoiceWorks[ingest.ProductId];
|
||||
Dictionary<int, VoiceWorkCreator> existingCreatorLinks = voiceWork.VoiceWorkCreators.ToDictionary(x => x.CreatorId);
|
||||
|
||||
int position = 1;
|
||||
|
||||
foreach (string creatorName in ingest.Creators)
|
||||
{
|
||||
Creator creator = something.Creators[creatorName];
|
||||
|
||||
if (!existingCreatorLinks.TryGetValue(creator.CreatorId, out VoiceWorkCreator? voiceWorkCreator))
|
||||
{
|
||||
voiceWorkCreator = new VoiceWorkCreator
|
||||
{
|
||||
VoiceWork = voiceWork,
|
||||
Creator = creator
|
||||
};
|
||||
|
||||
dbContext.VoiceWorkCreators.Add(voiceWorkCreator);
|
||||
}
|
||||
|
||||
voiceWorkCreator.Position = position++;
|
||||
voiceWorkCreator.IsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<SetVoiceWorkFavoriteResponse> SetFavoriteAsync(SetVoiceWorkFavoriteRequest request, CancellationToken cancellationToken)
|
||||
{
|
||||
VoiceWork voiceWork = await GetVoiceWorkAsync(request.VoiceWorkId, cancellationToken);
|
||||
voiceWork.Favorite = request.IsFavorite;
|
||||
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new SetVoiceWorkFavoriteResponse(request.VoiceWorkId, request.IsFavorite);
|
||||
}
|
||||
|
||||
private async Task<VoiceWork> GetVoiceWorkAsync(int voiceWorkId, CancellationToken cancellationToken)
|
||||
{
|
||||
return await context.VoiceWorks.FirstOrDefaultAsync(voiceWork => voiceWork.VoiceWorkId == voiceWorkId, cancellationToken)
|
||||
return await dbContext.VoiceWorks.FirstOrDefaultAsync(voiceWork => voiceWork.VoiceWorkId == voiceWorkId, cancellationToken)
|
||||
?? throw new KeyNotFoundException($"Voice Work {voiceWorkId} not found.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user