Files
sessionzero-cs/SzCore/SzDataHandler.cs

246 lines
9.3 KiB
C#

using SzCore.DataObjects;
namespace SzCore;
public class SzDataHandler
{
private readonly Dictionary<string, SzDataset> _loadedDatasets = [];
private readonly Dictionary<string, ISzTemplate> _loadedTemplates = [];
public SzDataHandler() { }
public void ClearCache()
{
_loadedDatasets.Clear();
_loadedTemplates.Clear();
}
#region Datasets
public async Task<SzResult<bool>> SaveDatasetAsync(SzDataset dataset, CancellationToken ct = default)
{
var datasetPath = Path.Combine(SZ.LocalFileManager.DatasetsPath, dataset.Id, "dataset.json");
try
{
var json = SZ.Parser.SerializeDatasetToJson(dataset);
var success = await SZ.LocalFileManager.SaveFileAsync(datasetPath, json, ct);
return success ? SzResult<bool>.Success(true) : SzResult<bool>.Failure("Failed to write dataset file.");
}
catch (Exception e)
{
SZ.Logger.LogError("Error saving dataset: " + e.Message);
return SzResult<bool>.Failure(e.Message);
}
}
public async Task<SzResult<SzDataset>> LoadDatasetAsync(string datasetId, CancellationToken ct = default)
{
if (_loadedDatasets.TryGetValue(datasetId, out SzDataset? value))
return SzResult<SzDataset>.Success(value);
var datasetPath = Path.Combine(SZ.LocalFileManager.DatasetsPath, datasetId, "dataset.json");
var json = await SZ.LocalFileManager.LoadFileAsync(datasetPath, ct);
if (json is null)
return SzResult<SzDataset>.Failure($"Could not find dataset file for ID '{datasetId}'");
var parsedDataset = SZ.Parser.DeserializeDataset(json);
if (parsedDataset is null)
return SzResult<SzDataset>.Failure($"Failed to parse dataset JSON for ID '{datasetId}'");
_loadedDatasets.TryAdd(parsedDataset.Id, parsedDataset);
return SzResult<SzDataset>.Success(parsedDataset);
}
public async Task<SzResult<bool>> DeleteDatasetAsync(string datasetId)
{
return await Task.Run(() => {
try
{
var path = Path.Combine(SZ.LocalFileManager.DatasetsPath, datasetId);
if (Directory.Exists(path)) Directory.Delete(path, true);
_loadedDatasets.Remove(datasetId);
return SzResult<bool>.Success(true);
}
catch (Exception e)
{
return SzResult<bool>.Failure(e.Message);
}
});
}
public async Task<SzResult<SzDataset>> CreateDatasetAsync(string name, string templateId, string? id = null, Guid? templateUuid = null)
{
if (string.IsNullOrEmpty(name)) return SzResult<SzDataset>.Failure("Name empty.");
var templateResult = await LoadTemplateAsync<SzDataObjectTemplate>(templateId);
if (!templateResult.IsSuccess || templateResult.Value is null)
return SzResult<SzDataset>.Failure($"Template '{templateId}' not found.");
var newDataset = new SzDataset()
{
Name = name,
Id = id ?? name.ToLower().Replace(" ", "-").Trim(),
DataObjectTemplateId = templateResult.Value.Id,
DataObjectTemplateUuid = templateUuid,
DataObjectType = templateResult.Value.DataObjectType,
Uuid = Guid.NewGuid()
};
return SzResult<SzDataset>.Success(newDataset);
}
public async Task<SzResult<string>> GetFieldValueFromPath(string path)
{
var parts = path.Split('.');
if (parts.Length < 3) return SzResult<string>.Failure("Not enough arguments in path");
var datasetId = parts[0];
var dataObjectId = parts[1];
var fieldPath = string.Join(".", parts.Skip(2));
var datasetResult = await LoadDatasetAsync(datasetId);
if (!datasetResult.IsSuccess)
return SzResult<string>.Failure($"Could not get field value, dataset with id '{datasetId}' could not be loaded: {datasetResult.Error}");
var dataset = datasetResult.Value;
if (dataset is null) return SzResult<string>.Failure("Dataset was null somehow");
if (!dataset.DataObjects.TryGetValue(dataObjectId, out var dataObject))
return SzResult<string>.Failure($"Data object {dataObjectId} does not exist in dataset {datasetId}");
if (!dataObject.Fields.TryGetValue(fieldPath, out var field))
return SzResult<string>.Failure($"Field {fieldPath} does not exist in Data Object {dataObjectId}");
return SzResult<string>.Success(field.Value);
}
#endregion
#region Templates
public async Task<SzResult<bool>> SaveTemplateAsync(ISzTemplate template, CancellationToken ct = default)
{
var templatePath = Path.Combine(SZ.LocalFileManager.TemplatesPath, template.Id, "template.json");
try
{
var json = SZ.Parser.SerializeTemplateToJson(template);
var success = await SZ.LocalFileManager.SaveFileAsync(templatePath, json, ct);
return success ? SzResult<bool>.Success(true) : SzResult<bool>.Failure("Failed to write template file.");
}
catch (Exception e)
{
return SzResult<bool>.Failure(e.Message);
}
}
public async Task<SzResult<T>> LoadTemplateAsync<T>(string templateId, CancellationToken ct = default) where T : ISzTemplate
{
if (_loadedTemplates.TryGetValue(templateId, out ISzTemplate? cachedTemplate))
return SzResult<T>.Success((T)cachedTemplate);
var path = Path.Combine(SZ.LocalFileManager.TemplatesPath, templateId, "template.json");
var json = await SZ.LocalFileManager.LoadFileAsync(path, ct);
if (json is null) return SzResult<T>.Failure($"Template '{templateId}' not found.");
var parsed = SZ.Parser.DeserializeTemplate<T>(json);
if (parsed is null) return SzResult<T>.Failure("Parse error.");
_loadedTemplates.TryAdd(parsed.Id, parsed);
return SzResult<T>.Success(parsed);
}
public async Task<SzResult<bool>> DeleteTemplateAsync(string templateId)
{
return await Task.Run(() => {
try
{
var path = Path.Combine(SZ.LocalFileManager.TemplatesPath, templateId);
if (Directory.Exists(path)) Directory.Delete(path, true);
_loadedTemplates.Remove(templateId);
return SzResult<bool>.Success(true);
}
catch (Exception e)
{
return SzResult<bool>.Failure(e.Message);
}
});
}
#endregion
#region Synchronous Creation Logic
public SzResult<SzTemplateField> CreateTemplateField(string id, SzFieldType fieldType, bool isList = false, string? defaultValue = null, bool isSpecialType = false, string? specialTypeValue = null)
{
if (string.IsNullOrEmpty(id)) return SzResult<SzTemplateField>.Failure("ID cannot be empty.");
return SzResult<SzTemplateField>.Success(new SzTemplateField()
{
Id = id,
FieldType = fieldType,
IsList = isList,
IsSpecialType = isSpecialType,
DefaultValue = defaultValue ?? "",
SpecialTypeValue = specialTypeValue ?? ""
});
}
public SzResult<SzDataObjectTemplate> CreateDataObjectTemplate(string name, string dataObjectType, string? id = null, string? description = null, List<SzTemplateField>? fields = null)
{
var newTemplate = new SzDataObjectTemplate()
{
Name = name,
Id = id ?? name.ToLower().Replace(" ", "-").Trim(),
DataObjectType = dataObjectType,
Uuid = Guid.NewGuid(),
Description = description ?? ""
};
if (fields != null)
{
foreach (var field in fields) newTemplate.TemplateFields.TryAdd(field.Id, field);
}
return SzResult<SzDataObjectTemplate>.Success(newTemplate);
}
public SzResult<SzDataObject> CreateDataObject(SzDataObjectTemplate template, string name, string? id = null)
{
var dataObject = new SzDataObject()
{
Name = name,
Id = id ?? name.ToLower().Replace(" ", "-").Trim()
};
var fieldsResult = CreateFieldsFromTemplate(template);
if (!fieldsResult.IsSuccess) return SzResult<SzDataObject>.Failure(fieldsResult.Error);
dataObject.Fields = fieldsResult.Value!;
return SzResult<SzDataObject>.Success(dataObject);
}
public SzResult<Dictionary<string, SzField>> CreateFieldsFromTemplate(ISzTemplate template)
{
var fields = new Dictionary<string, SzField>();
foreach (var tempField in template.TemplateFields.Values)
{
fields.Add(tempField.Id, new SzField { Id = tempField.Id, FieldType = tempField.FieldType, IsList = tempField.IsList });
}
return SzResult<Dictionary<string, SzField>>.Success(fields);
}
#endregion
#region Bulk Operations
public async Task LoadAllDatasetsAsync(CancellationToken ct = default)
{
_loadedDatasets.Clear();
if (!Directory.Exists(SZ.LocalFileManager.DatasetsPath)) return;
var dirs = Directory.GetDirectories(SZ.LocalFileManager.DatasetsPath);
foreach (var dir in dirs)
{
var id = Path.GetFileName(dir);
await LoadDatasetAsync(id, ct);
}
}
#endregion
}