added database to store metadata
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
using System.Linq;
|
||||
using SQLite;
|
||||
|
||||
namespace ParadoxSaveParser.WebAPI.Database;
|
||||
|
||||
public class DatabaseConnector
|
||||
{
|
||||
private readonly int _uploadsLifetimeDays;
|
||||
private readonly SQLiteAsyncConnection _db;
|
||||
private readonly ContextLogger _logger;
|
||||
|
||||
public DatabaseConnector(string databasePath, int uploadsLifetimeDays, ILogger logger)
|
||||
{
|
||||
_uploadsLifetimeDays = uploadsLifetimeDays;
|
||||
_db = new SQLiteAsyncConnection(databasePath);
|
||||
_logger = new ContextLogger("Database", logger);
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await _db.CreateTableAsync<SaveFileMetadata>();
|
||||
}
|
||||
|
||||
public async Task<SaveFileMetadata?> GetMetadata(string id)
|
||||
{
|
||||
return (await _db.QueryAsync<SaveFileMetadata>(
|
||||
"select * from SaveFileMetadata where id = ?", id))
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task<SaveFileMetadata> CreateMetadata(Game game)
|
||||
{
|
||||
var meta = new SaveFileMetadata
|
||||
{
|
||||
id = Guid.NewGuid().ToString(),
|
||||
game = game,
|
||||
status = SaveFileProcessingStatus.Initialized,
|
||||
uploadDateTime = DateTime.Now
|
||||
};
|
||||
await _db.InsertAsync(meta);
|
||||
return meta;
|
||||
}
|
||||
|
||||
public async Task UpdateMetadataStatus(SaveFileMetadata meta, SaveFileProcessingStatus status)
|
||||
{
|
||||
meta.status = status;
|
||||
await _db.UpdateAsync(meta);
|
||||
}
|
||||
|
||||
public async Task SetMetadataError(SaveFileMetadata meta, string errorMessage)
|
||||
{
|
||||
meta.errorMessage = errorMessage;
|
||||
await UpdateMetadataStatus(meta, SaveFileProcessingStatus.Error);
|
||||
DeleteAssociatedFiles(meta);
|
||||
}
|
||||
|
||||
public async Task DeleteMetadata(SaveFileMetadata meta)
|
||||
{
|
||||
_logger.LogDebug($"Deleting save file (id: {meta.id} status: {meta.status} " +
|
||||
$"uploadDate: {meta.uploadDateTime:yyyy/MM/dd})");
|
||||
await _db.DeleteAsync(meta);
|
||||
DeleteAssociatedFiles(meta);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WARNING: Call this method only when no parsing operations are running.
|
||||
/// </summary>
|
||||
public async Task DeleteInvalidData()
|
||||
{
|
||||
_logger.LogInfo("Deleting invalid data...");
|
||||
|
||||
var expirationDate = DateTime.Now.AddDays(-_uploadsLifetimeDays);
|
||||
var metadataTable = _db.Table<SaveFileMetadata>();
|
||||
int rowCount = await metadataTable.CountAsync();
|
||||
int i = 0;
|
||||
int deleteCount = 0;
|
||||
while(i < rowCount)
|
||||
{
|
||||
var meta = await metadataTable.ElementAtAsync(i)!;
|
||||
if(meta.status != SaveFileProcessingStatus.Done ||
|
||||
meta.uploadDateTime < expirationDate ||
|
||||
!meta.AssociatedFilesExist())
|
||||
{
|
||||
deleteCount++;
|
||||
await DeleteMetadata(meta);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
_logger.LogInfo($"Deleted {deleteCount} invalid records");
|
||||
}
|
||||
|
||||
private void TryDeleteFile(IOPath file)
|
||||
{
|
||||
if (!File.Exists(file)) return;
|
||||
_logger.LogDebug($"Deleting file '{file}'");
|
||||
File.Delete(file);
|
||||
}
|
||||
|
||||
private void DeleteAssociatedFiles(SaveFileMetadata meta)
|
||||
{
|
||||
TryDeleteFile(meta.GetSaveFilePath());
|
||||
TryDeleteFile(meta.GetParsedDataPath());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ParadoxSaveParser.WebAPI.Database;
|
||||
|
||||
public enum SaveFileProcessingStatus
|
||||
{
|
||||
Initialized,
|
||||
Uploaded,
|
||||
Parsing,
|
||||
SavingResults,
|
||||
Done,
|
||||
Error,
|
||||
}
|
||||
|
||||
public class SaveFileMetadata
|
||||
{
|
||||
[SQLite.PrimaryKey]
|
||||
[SQLite.NotNull]
|
||||
public string id { get; init; } = null!;
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
[SQLite.NotNull]
|
||||
public Game game { get; init; }
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
[SQLite.NotNull]
|
||||
public SaveFileProcessingStatus status { get; set; }
|
||||
|
||||
[SQLite.NotNull]
|
||||
public DateTime uploadDateTime { get; set; }
|
||||
|
||||
// if error occured during parsing, it's message is saved here
|
||||
// status stays the same as when error occured
|
||||
public string? errorMessage { get; set; }
|
||||
|
||||
|
||||
public IOPath GetSaveFilePath() => Path.Concat(PathHelper.SAVES_DIR, id + ".eu4");
|
||||
|
||||
public IOPath GetParsedDataPath() => Path.Concat(PathHelper.PARSED_DIR, id + ".parsed.json");
|
||||
|
||||
public bool AssociatedFilesExist()
|
||||
{
|
||||
return File.Exists(GetSaveFilePath()) && File.Exists(GetParsedDataPath());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user