Add phase 1 critical import tool

This commit is contained in:
2026-03-14 01:10:44 +01:00
parent 44af81cc38
commit f70d610c92
25 changed files with 851 additions and 166 deletions

View File

@@ -0,0 +1,133 @@
using Microsoft.EntityFrameworkCore;
using RolemasterDb.App.Data;
using RolemasterDb.App.Domain;
using RolemasterDb.ImportTool.Parsing;
namespace RolemasterDb.ImportTool;
public sealed class CriticalImportLoader(string databasePath)
{
public async Task<int> ResetCriticalsAsync(CancellationToken cancellationToken = default)
{
await using var dbContext = CreateDbContext();
await dbContext.Database.EnsureCreatedAsync(cancellationToken);
var removedTableCount = await dbContext.CriticalTables.CountAsync(cancellationToken);
await using var transaction = await dbContext.Database.BeginTransactionAsync(cancellationToken);
await dbContext.CriticalResults.ExecuteDeleteAsync(cancellationToken);
await dbContext.CriticalGroups.ExecuteDeleteAsync(cancellationToken);
await dbContext.CriticalColumns.ExecuteDeleteAsync(cancellationToken);
await dbContext.CriticalRollBands.ExecuteDeleteAsync(cancellationToken);
await dbContext.CriticalTables.ExecuteDeleteAsync(cancellationToken);
await transaction.CommitAsync(cancellationToken);
return removedTableCount;
}
public async Task<ImportCommandResult> LoadAsync(ParsedCriticalTable table, CancellationToken cancellationToken = default)
{
await using var dbContext = CreateDbContext();
await dbContext.Database.EnsureCreatedAsync(cancellationToken);
await using var transaction = await dbContext.Database.BeginTransactionAsync(cancellationToken);
await DeleteTableAsync(dbContext, table.Slug, cancellationToken);
var entity = new CriticalTable
{
Slug = table.Slug,
DisplayName = table.DisplayName,
Family = table.Family,
SourceDocument = table.SourceDocument,
Notes = table.Notes
};
entity.Columns = table.Columns
.Select(item => new CriticalColumn
{
ColumnKey = item.ColumnKey,
Label = item.Label,
Role = item.Role,
SortOrder = item.SortOrder
})
.ToList();
entity.RollBands = table.RollBands
.Select(item => new CriticalRollBand
{
Label = item.Label,
MinRoll = item.MinRoll,
MaxRoll = item.MaxRoll,
SortOrder = item.SortOrder
})
.ToList();
var columnsByKey = entity.Columns.ToDictionary(item => item.ColumnKey, StringComparer.OrdinalIgnoreCase);
var rollBandsByLabel = entity.RollBands.ToDictionary(item => item.Label, StringComparer.OrdinalIgnoreCase);
entity.Results = table.Results
.Select(item => new CriticalResult
{
CriticalColumn = columnsByKey[item.ColumnKey],
CriticalRollBand = rollBandsByLabel[item.RollBandLabel],
RawCellText = item.RawCellText,
DescriptionText = item.DescriptionText,
RawAffixText = item.RawAffixText,
ParsedJson = "{}",
ParseStatus = "raw"
})
.ToList();
dbContext.CriticalTables.Add(entity);
await dbContext.SaveChangesAsync(cancellationToken);
await transaction.CommitAsync(cancellationToken);
return new ImportCommandResult(entity.Slug, entity.Columns.Count, entity.RollBands.Count, entity.Results.Count);
}
private RolemasterDbContext CreateDbContext()
{
var options = new DbContextOptionsBuilder<RolemasterDbContext>()
.UseSqlite($"Data Source={databasePath}")
.Options;
return new RolemasterDbContext(options);
}
private static async Task DeleteTableAsync(
RolemasterDbContext dbContext,
string slug,
CancellationToken cancellationToken)
{
var tableId = await dbContext.CriticalTables
.Where(item => item.Slug == slug)
.Select(item => (int?)item.Id)
.SingleOrDefaultAsync(cancellationToken);
if (tableId is null)
{
return;
}
await dbContext.CriticalResults
.Where(item => item.CriticalTableId == tableId.Value)
.ExecuteDeleteAsync(cancellationToken);
await dbContext.CriticalGroups
.Where(item => item.CriticalTableId == tableId.Value)
.ExecuteDeleteAsync(cancellationToken);
await dbContext.CriticalColumns
.Where(item => item.CriticalTableId == tableId.Value)
.ExecuteDeleteAsync(cancellationToken);
await dbContext.CriticalRollBands
.Where(item => item.CriticalTableId == tableId.Value)
.ExecuteDeleteAsync(cancellationToken);
await dbContext.CriticalTables
.Where(item => item.Id == tableId.Value)
.ExecuteDeleteAsync(cancellationToken);
}
}