Compare commits
6
Commits
bc601379b3
...
d48dc62fe7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d48dc62fe7 | ||
|
|
3168c9c406 | ||
|
|
7c2f2349c0 | ||
|
|
9708bf31e2 | ||
|
|
bf016df060 | ||
|
|
8a0cdcb943 |
+1
-1
@@ -121,7 +121,7 @@ csharp_style_conditional_delegate_call = true
|
|||||||
# Предпочтения модификатора
|
# Предпочтения модификатора
|
||||||
csharp_prefer_static_anonymous_function = true
|
csharp_prefer_static_anonymous_function = true
|
||||||
csharp_prefer_static_local_function = true
|
csharp_prefer_static_local_function = true
|
||||||
csharp_preferred_modifier_order = public, private, protected, readonly, file, static, extern, internal, virtual, abstract, override, sealed, new, unsafe, required, volatile, async:suggestion
|
csharp_preferred_modifier_order = public, private, protected, file, static, extern, internal, virtual, abstract, override, sealed, readonly, new, unsafe, required, volatile, async:suggestion
|
||||||
csharp_style_prefer_readonly_struct = true
|
csharp_style_prefer_readonly_struct = true
|
||||||
csharp_style_prefer_readonly_struct_member = true
|
csharp_style_prefer_readonly_struct_member = true
|
||||||
|
|
||||||
|
|||||||
@@ -3,29 +3,35 @@
|
|||||||
namespace Pf2eDataScrapper.Importers;
|
namespace Pf2eDataScrapper.Importers;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Абстрактный класс импортёра
|
/// Абстрактный класс импортёра.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal abstract class AbstractImporter
|
internal abstract class AbstractImporter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Отображаемое имя импортёра
|
/// Отображаемое имя импортёра.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Короткое имя импортёра
|
/// Короткое имя импортёра.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract string Slug { get; }
|
public abstract string Slug { get; }
|
||||||
|
|
||||||
public abstract AbstractImporterRepository Repository { get; }
|
public abstract AbstractImporterRepository Repository { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Путь к директории с данными для импортёра
|
/// Путь к директории с данными для импортёра.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Dir => Path.Combine(EnvSettings.DataDirPath, Slug);
|
public string Dir => Path.Combine(EnvSettings.DataDirPath, Slug);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Метод подготовки данных для импорта
|
/// Перечисление процессоров, которые будут использоваться для обработки данных.
|
||||||
|
/// При пустом массиве будут обработаны все доступные процессоры.
|
||||||
|
/// </summary>
|
||||||
|
public string[] ProcessorNames { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Метод подготовки данных для импорта.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void Prepare();
|
public abstract void Prepare();
|
||||||
|
|
||||||
@@ -35,7 +41,7 @@ internal abstract class AbstractImporter
|
|||||||
public abstract void Import();
|
public abstract void Import();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Построение схем данных
|
/// Построение схем данных.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void BuildSchemas();
|
public abstract void BuildSchemas();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ internal class AonprdImporter : AbstractImporter
|
|||||||
public override void Import()
|
public override void Import()
|
||||||
{
|
{
|
||||||
AonprdDataBuilder builder = new(Loader);
|
AonprdDataBuilder builder = new(Loader);
|
||||||
|
builder.Processors.UseOnlyNames(ProcessorNames);
|
||||||
|
|
||||||
builder.TruncateTables();
|
builder.TruncateTables();
|
||||||
builder.Build();
|
builder.Build();
|
||||||
|
|||||||
+29
-1
@@ -14,7 +14,9 @@ internal class AonprdProcessorCollection
|
|||||||
public int Priority = -1;
|
public int Priority = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly List<ProcessorItem> Items = [];
|
private readonly List<ProcessorItem> _allItems;
|
||||||
|
|
||||||
|
public List<ProcessorItem> Items { get; private set; } = [];
|
||||||
|
|
||||||
public AonprdProcessorCollection()
|
public AonprdProcessorCollection()
|
||||||
{
|
{
|
||||||
@@ -50,6 +52,8 @@ internal class AonprdProcessorCollection
|
|||||||
|
|
||||||
Items.Add(new(attribute, constructor));
|
Items.Add(new(attribute, constructor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_allItems = Items.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckDependencies()
|
private void CheckDependencies()
|
||||||
@@ -109,4 +113,28 @@ internal class AonprdProcessorCollection
|
|||||||
yield return item;
|
yield return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UseOnlyNames(string[] processorNames)
|
||||||
|
{
|
||||||
|
Dictionary<string, bool> nameFlags = processorNames.ToDictionary(name => name, _ => false);
|
||||||
|
|
||||||
|
while (nameFlags.Values.Any(v => !v))
|
||||||
|
{
|
||||||
|
foreach (
|
||||||
|
KeyValuePair<string, bool> pair in nameFlags.Where(pair => !pair.Value).ToList()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ProcessorItem item = _allItems.First(item => item.Attribute.Name == pair.Key);
|
||||||
|
|
||||||
|
foreach (string dependency in item.Attribute.Dependencies)
|
||||||
|
{
|
||||||
|
nameFlags.TryAdd(dependency, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
nameFlags[pair.Key] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Items = _allItems.Where(item => nameFlags.ContainsKey(item.Attribute.Name)).ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -21,7 +21,7 @@ internal partial class StringHelper
|
|||||||
{
|
{
|
||||||
MarkdownLinkSplit result = new();
|
MarkdownLinkSplit result = new();
|
||||||
|
|
||||||
Match match = MarkdownRegex().Match(input);
|
Match match = LinkRegex().Match(input);
|
||||||
if (match.Captures.Count > 0)
|
if (match.Captures.Count > 0)
|
||||||
{
|
{
|
||||||
result.Links.Add(
|
result.Links.Add(
|
||||||
@@ -34,7 +34,7 @@ internal partial class StringHelper
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Suffix = MarkdownRegex().Replace(input, "");
|
result.Suffix = LinkRegex().Replace(input, "");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ internal partial class StringHelper
|
|||||||
public static partial Regex SourceSuffixRegex();
|
public static partial Regex SourceSuffixRegex();
|
||||||
|
|
||||||
[GeneratedRegex(@"(.*?)\[(.*?)\]\((.*?)\)")]
|
[GeneratedRegex(@"(.*?)\[(.*?)\]\((.*?)\)")]
|
||||||
public static partial Regex MarkdownRegex();
|
public static partial Regex LinkRegex();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class MarkdownLinkSplit
|
internal class MarkdownLinkSplit
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Helpers;
|
||||||
|
using Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||||
|
using Pf2eModel.Model.Base;
|
||||||
|
using Pf2eModel.Model.Base.Source;
|
||||||
|
using Pf2eModel.Model.Common.I18n;
|
||||||
|
|
||||||
|
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
|
||||||
|
|
||||||
|
internal class LegacyEntityHandler
|
||||||
|
{
|
||||||
|
public string LegacyId { get; private set; }
|
||||||
|
|
||||||
|
public string LegacyName { get; private set; } = "";
|
||||||
|
|
||||||
|
public List<EntitySource> LegacySources { get; private set; } = [];
|
||||||
|
|
||||||
|
public bool LegacyPrepared { get; private set; } = false;
|
||||||
|
|
||||||
|
public List<Entity> RemasterEntities = [];
|
||||||
|
|
||||||
|
public LegacyEntityHandler(AbstractEntityProcessor processor)
|
||||||
|
{
|
||||||
|
LegacyId = processor.Input.GetRequired<string>("id");
|
||||||
|
Prepare(processor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LegacyEntityHandler(string legacyId, Entity remasterEntity)
|
||||||
|
{
|
||||||
|
LegacyId = legacyId;
|
||||||
|
LegacyPrepared = false;
|
||||||
|
RemasterEntities.Add(remasterEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Prepare(AbstractEntityProcessor processor)
|
||||||
|
{
|
||||||
|
if (LegacyPrepared)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LegacyName = processor.Input.GetRequired<string>("name");
|
||||||
|
LegacySources = processor.GetSources();
|
||||||
|
LegacyPrepared = true;
|
||||||
|
|
||||||
|
foreach (Entity remasterEntity in RemasterEntities)
|
||||||
|
{
|
||||||
|
Apply(remasterEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply(Entity remasterEntity)
|
||||||
|
{
|
||||||
|
if (!remasterEntity.Name.Contains(LegacyName))
|
||||||
|
{
|
||||||
|
remasterEntity.Name[LocaleType.LegacyEnglish] = LegacyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (EntitySource legacySource in LegacySources)
|
||||||
|
{
|
||||||
|
EntitySource entitySource = new()
|
||||||
|
{
|
||||||
|
Entity = remasterEntity,
|
||||||
|
Source = legacySource.Source,
|
||||||
|
Suffix = legacySource.Suffix,
|
||||||
|
IsRemaster = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
remasterEntity.Sources.Add(entitySource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+77
-65
@@ -29,18 +29,17 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
|||||||
{
|
{
|
||||||
if (Input.GetOptional<JArray>("remaster_id") is not null)
|
if (Input.GetOptional<JArray>("remaster_id") is not null)
|
||||||
{
|
{
|
||||||
string id = Input.GetRequired<string>("id");
|
LegacyEntityHandler handler = new(this);
|
||||||
string name = Input.GetRequired<string>("name");
|
LegacyHandlers.Add(handler);
|
||||||
|
throw new LegacyItemException(handler.LegacyName);
|
||||||
ProcessLegacy(id, name);
|
|
||||||
throw new LegacyItemException(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AddEntity();
|
AddEntity();
|
||||||
AddAlias();
|
|
||||||
AddSource();
|
AddSource();
|
||||||
AddExternal();
|
AddExternal();
|
||||||
AddTraits();
|
AddTraits();
|
||||||
|
|
||||||
|
ProcessLegacy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Save()
|
public override void Save()
|
||||||
@@ -49,6 +48,8 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
|||||||
Context.SaveChanges();
|
Context.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Description generation
|
||||||
|
|
||||||
protected virtual string[] AddedDescriptionPaths() => [];
|
protected virtual string[] AddedDescriptionPaths() => [];
|
||||||
|
|
||||||
protected string AddedDescription(string path) =>
|
protected string AddedDescription(string path) =>
|
||||||
@@ -60,6 +61,8 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
|||||||
protected virtual string GetDescription() =>
|
protected virtual string GetDescription() =>
|
||||||
Input.GetRequired<string>("markdown") + AddedDescription(AddedDescriptionPaths());
|
Input.GetRequired<string>("markdown") + AddedDescription(AddedDescriptionPaths());
|
||||||
|
|
||||||
|
// Entity generation
|
||||||
|
|
||||||
protected virtual void AddEntity()
|
protected virtual void AddEntity()
|
||||||
{
|
{
|
||||||
Entity.Id = Helper.NextEntityId;
|
Entity.Id = Helper.NextEntityId;
|
||||||
@@ -78,57 +81,12 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
|||||||
Context.Entities.Add(Entity);
|
Context.Entities.Add(Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AddAlias()
|
|
||||||
{
|
|
||||||
JArray? legacyIdArray = Input.GetOptional<JArray>("legacy_id");
|
|
||||||
|
|
||||||
if (legacyIdArray is null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string legacyId = legacyIdArray[0].ToString();
|
|
||||||
|
|
||||||
if (LegacyAliases.TryGetValue(legacyId, out string? legacyName))
|
|
||||||
{
|
|
||||||
// if (legacyName != Entity.Name[LocaleType.English])
|
|
||||||
Entity.Name[LocaleType.LegacyEnglish] = legacyName;
|
|
||||||
|
|
||||||
LegacyAliases.Remove(legacyId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RemasterWithoutLegacy.Add(legacyId, Entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void AddSource()
|
protected virtual void AddSource()
|
||||||
{
|
{
|
||||||
string name = Input.GetRequired<string>("source[0]");
|
foreach (EntitySource entitySource in GetSources())
|
||||||
|
|
||||||
Source? source = Context.Sources.FirstOrDefault(s => s.Name == name);
|
|
||||||
|
|
||||||
if (source == null)
|
|
||||||
{
|
{
|
||||||
source = new()
|
Entity.Sources.Add(entitySource);
|
||||||
{
|
|
||||||
Name = name,
|
|
||||||
Category = Input.EnumRequired<SourceCategory>("primary_source_category"),
|
|
||||||
ReleaseDate = DateOnly.Parse(Input.GetRequired<string>("release_date")),
|
|
||||||
};
|
|
||||||
|
|
||||||
Context.Sources.Add(source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EntitySource entitySource = new()
|
|
||||||
{
|
|
||||||
Entity = Entity,
|
|
||||||
Source = source,
|
|
||||||
Suffix = StringHelper.ResolveSource(Input.GetRequired<string>("source_markdown")),
|
|
||||||
IsRemaster = Input.GetOptional<JArray>("legacy_id") is not null,
|
|
||||||
};
|
|
||||||
|
|
||||||
Context.EntitySources.Add(entitySource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AddExternal()
|
protected virtual void AddExternal()
|
||||||
@@ -179,19 +137,75 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ProcessLegacy(string id, string name)
|
protected virtual void ProcessLegacy()
|
||||||
{
|
{
|
||||||
if (RemasterWithoutLegacy.TryGetValue(id, out Entity? remastered))
|
JArray? legacyIdArray = Input.GetOptional<JArray>("legacy_id");
|
||||||
{
|
|
||||||
// if (remastered.ToString() != name)
|
|
||||||
remastered.Name[LocaleType.LegacyEnglish] = name;
|
|
||||||
|
|
||||||
RemasterWithoutLegacy.Remove(id);
|
if (legacyIdArray is null)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
LegacyAliases.Add(id, name);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string[] legacyIds = legacyIdArray.ToArray().Select(t => t.ToString()).ToArray();
|
||||||
|
|
||||||
|
if (legacyIds.Length == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string legacyId in legacyIds)
|
||||||
|
{
|
||||||
|
LegacyEntityHandler? handler = LegacyHandlers.FirstOrDefault(h =>
|
||||||
|
h.LegacyId == legacyId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (handler is not null)
|
||||||
|
{
|
||||||
|
handler.Apply(Entity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handler = new(legacyId, Entity);
|
||||||
|
LegacyHandlers.Add(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EntitySource> GetSources()
|
||||||
|
{
|
||||||
|
string[] sourceNames = Input
|
||||||
|
.GetRequired<JArray>("source")
|
||||||
|
.Select(token => token.ToString())
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (sourceNames.Length == 0)
|
||||||
|
{
|
||||||
|
throw new(
|
||||||
|
$"Source for entity with id \"{Entity.Name[LocaleType.English]}\" "
|
||||||
|
+ $"(Aonprd id \"{Input.GetRequired<string>("id")}\") is not found"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<EntitySource> entitySources = new();
|
||||||
|
|
||||||
|
foreach (string sourceName in sourceNames)
|
||||||
|
{
|
||||||
|
Source source =
|
||||||
|
Context.Sources.FirstOrDefault(s => s.Name == sourceName)
|
||||||
|
?? throw new($"Source \"{sourceName}\" did not found");
|
||||||
|
|
||||||
|
EntitySource entitySource = new()
|
||||||
|
{
|
||||||
|
Entity = Entity,
|
||||||
|
Source = source,
|
||||||
|
Suffix = StringHelper.ResolveSource(Input.GetRequired<string>("source_markdown")),
|
||||||
|
IsRemaster = Input.GetOptional<JArray>("legacy_id") is not null,
|
||||||
|
};
|
||||||
|
|
||||||
|
entitySources.Add(entitySource);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entitySources;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GenerateExtra(params string[] args)
|
public string GenerateExtra(params string[] args)
|
||||||
@@ -214,9 +228,7 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
|||||||
return isLowercase ? hash.ToLower() : hash;
|
return isLowercase ? hash.ToLower() : hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static readonly Dictionary<string, string> LegacyAliases = [];
|
protected static readonly List<LegacyEntityHandler> LegacyHandlers = [];
|
||||||
|
|
||||||
protected static readonly Dictionary<string, Entity> RemasterWithoutLegacy = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LegacyItemException(string name)
|
public class LegacyItemException(string name)
|
||||||
|
|||||||
+2
-11
@@ -9,22 +9,13 @@ internal class ActionProcessor(AonprdProcessorInput input) : AbstractEntityProce
|
|||||||
|
|
||||||
public override Pf2eModel.Model.Structure.Action Object { get; } = new();
|
public override Pf2eModel.Model.Structure.Action Object { get; } = new();
|
||||||
|
|
||||||
private bool _skipping = false;
|
public override void Add() => Context.Actions.Add(Object);
|
||||||
|
|
||||||
public override void Add()
|
|
||||||
{
|
|
||||||
if (!_skipping)
|
|
||||||
{
|
|
||||||
Context.Actions.Add(Object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Process()
|
public override void Process()
|
||||||
{
|
{
|
||||||
if (Input.GetRequired<string>("markdown").StartsWith("**Activate**"))
|
if (Input.GetRequired<string>("markdown").StartsWith("**Activate**"))
|
||||||
{
|
{
|
||||||
_skipping = true;
|
throw new SkipItemException(Input.GetRequired<string>("name"), "activating action");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Process();
|
base.Process();
|
||||||
|
|||||||
+1
-1
@@ -257,7 +257,7 @@ internal partial class RitualProcessor(AonprdProcessorInput input) : AbstractEnt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Замена символа ссылок
|
// Замена символа ссылок
|
||||||
input = StringHelper.MarkdownRegex().Replace(input, "$1[$2]{$3}");
|
input = StringHelper.LinkRegex().Replace(input, "$1[$2]{$3}");
|
||||||
input = input.Replace("(", "<").Replace(")", ">").Replace("{", "(").Replace("}", ")");
|
input = input.Replace("(", "<").Replace(")", ">").Replace("{", "(").Replace("}", ")");
|
||||||
|
|
||||||
if (input.EndsWith(';') || input.EndsWith(','))
|
if (input.EndsWith(';') || input.EndsWith(','))
|
||||||
|
|||||||
+115
@@ -0,0 +1,115 @@
|
|||||||
|
using System.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations.Operations;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Pf2eModel.Model.Common.I18n;
|
||||||
|
using Pf2eModel.Model.Enum;
|
||||||
|
using Pf2eModel.Model.Structure;
|
||||||
|
using Rule = Pf2eModel.Model.Structure.Rule;
|
||||||
|
|
||||||
|
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||||
|
|
||||||
|
[AonprdProcessor("rules")]
|
||||||
|
internal class RuleProcessor(AonprdProcessorInput input) : AbstractEntityProcessor(input)
|
||||||
|
{
|
||||||
|
public override EntityType Type => EntityType.Rule;
|
||||||
|
|
||||||
|
public override Rule Object { get; } = new();
|
||||||
|
|
||||||
|
public override void Add() => Context.Rules.Add(Object);
|
||||||
|
|
||||||
|
public override void Process()
|
||||||
|
{
|
||||||
|
base.Process();
|
||||||
|
|
||||||
|
string[] breadcrumbs = (Input.GetOptional<JArray>("breadcrumbs") ?? [])
|
||||||
|
.Select(token => token.ToString())
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
RuleStructureItem item = GetStructureItem(
|
||||||
|
[.. breadcrumbs, Entity.Name[LocaleType.English]]
|
||||||
|
);
|
||||||
|
|
||||||
|
item.IsHandled = true;
|
||||||
|
item.RuleId = Object.Id;
|
||||||
|
item.Id = Input.GetRequired<string>("id");
|
||||||
|
|
||||||
|
if (item.Parent?.IsHandled ?? false)
|
||||||
|
{
|
||||||
|
Object.ParentId = item.Parent.RuleId!;
|
||||||
|
// Object.Order = item.Parent.ChildrenOrder?.IndexOf(item.Id) ?? 0;
|
||||||
|
Object.Order = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.ChildrenOrder = [];
|
||||||
|
|
||||||
|
List<int> childrenIds = item
|
||||||
|
.Children.Select(i => i.RuleId)
|
||||||
|
.Where(id => id != null)
|
||||||
|
.OfType<int>()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
List<Rule> rules = Context.Rules.Where(i => childrenIds.Contains(i.Id)).ToList();
|
||||||
|
|
||||||
|
foreach (Rule rule in rules)
|
||||||
|
{
|
||||||
|
rule.Order = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* TODO
|
||||||
|
* Обработка порядка из полей
|
||||||
|
*
|
||||||
|
"next_link": {
|
||||||
|
"label": "Chapter 3: Classes",
|
||||||
|
"url": "/Rules.aspx?ID=134"
|
||||||
|
},
|
||||||
|
"previous_link": {
|
||||||
|
"label": "Chapter 1: Introduction",
|
||||||
|
"url": "/Rules.aspx?ID=1"
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly List<RuleStructureItem> Roots = [];
|
||||||
|
|
||||||
|
private RuleStructureItem GetStructureItem(string[] breadcrumbs, RuleStructureItem? from = null)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
List<RuleStructureItem> children = from?.Children ?? Roots;
|
||||||
|
|
||||||
|
if (breadcrumbs.Length == 0)
|
||||||
|
{
|
||||||
|
return from!;
|
||||||
|
}
|
||||||
|
|
||||||
|
string root = breadcrumbs[0];
|
||||||
|
RuleStructureItem? item = children.FirstOrDefault(i => i.Name == root);
|
||||||
|
|
||||||
|
if (item is null)
|
||||||
|
{
|
||||||
|
item = new(root, from);
|
||||||
|
children.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
breadcrumbs = breadcrumbs[1..];
|
||||||
|
from = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class RuleStructureItem(string name, RuleStructureItem? parent)
|
||||||
|
{
|
||||||
|
public string? Id { get; set; } = null;
|
||||||
|
|
||||||
|
public string Name { get; set; } = name;
|
||||||
|
|
||||||
|
public int? RuleId { get; set; } = null;
|
||||||
|
|
||||||
|
public bool IsHandled { get; set; } = false;
|
||||||
|
|
||||||
|
public RuleStructureItem? Parent { get; set; } = parent;
|
||||||
|
|
||||||
|
public List<string>? ChildrenOrder { get; set; } = null;
|
||||||
|
|
||||||
|
public List<RuleStructureItem> Children { get; } = [];
|
||||||
|
}
|
||||||
@@ -10,6 +10,9 @@ Pf2EFoundryImporter importer = new();
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
AonprdImporter importer = new();
|
AonprdImporter importer = new();
|
||||||
|
|
||||||
|
importer.ProcessorNames = ["rules"];
|
||||||
|
|
||||||
importer.Prepare();
|
importer.Prepare();
|
||||||
importer.Import();
|
importer.Import();
|
||||||
// importer.BuildSchemas();
|
// importer.BuildSchemas();
|
||||||
|
|||||||
+57
-2
@@ -13,7 +13,7 @@ using Pf2eModel.Model.Enum;
|
|||||||
namespace Pf2eModel.Migrations
|
namespace Pf2eModel.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(Pf2eDbContext))]
|
[DbContext(typeof(Pf2eDbContext))]
|
||||||
[Migration("20250506175505_1")]
|
[Migration("20250507112626_1")]
|
||||||
partial class _1
|
partial class _1
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -34,7 +34,7 @@ namespace Pf2eModel.Migrations
|
|||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_rarity", new[] { "common", "uncommon", "rare", "unique" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_rarity", new[] { "common", "uncommon", "rare", "unique" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "archetype", "background", "backpack", "campaign_feature", "class", "subclass_group", "subclass", "condition", "deity", "feat", "heritage", "spell", "ritual", "language" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "archetype", "background", "backpack", "campaign_feature", "class", "subclass_group", "subclass", "condition", "deity", "feat", "heritage", "spell", "ritual", "language", "rule" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_action_type", new[] { "passive", "action", "reaction", "free" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_action_type", new[] { "passive", "action", "reaction", "free" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_category", new[] { "uncategorized", "ancestry-feature", "class-feature", "calling", "class", "skill", "general", "ancestry", "bonus", "deityboon", "curse", "pfsboon", "campaign-feature" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_category", new[] { "uncategorized", "ancestry-feature", "class-feature", "calling", "class", "skill", "general", "ancestry", "bonus", "deityboon", "curse", "pfsboon", "campaign-feature" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "locale_type", new[] { "english", "legacy_english", "russian", "legacy", "hobby", "other" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "locale_type", new[] { "english", "legacy_english", "russian", "legacy", "hobby", "other" });
|
||||||
@@ -1395,6 +1395,37 @@ namespace Pf2eModel.Migrations
|
|||||||
b.ToTable("ritual_checks", (string)null);
|
b.ToTable("ritual_checks", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasColumnOrder(1);
|
||||||
|
|
||||||
|
b.PrimitiveCollection<string[]>("Breadcrumbs")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text[]")
|
||||||
|
.HasColumnName("breadcrumbs");
|
||||||
|
|
||||||
|
b.Property<int>("Order")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("order")
|
||||||
|
.HasColumnOrder(2);
|
||||||
|
|
||||||
|
b.Property<int?>("ParentId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("parent_id")
|
||||||
|
.HasColumnOrder(3);
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_rules");
|
||||||
|
|
||||||
|
b.HasIndex("ParentId")
|
||||||
|
.HasDatabaseName("ix_rules_parent_id");
|
||||||
|
|
||||||
|
b.ToTable("rules", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -2249,6 +2280,25 @@ namespace Pf2eModel.Migrations
|
|||||||
b.Navigation("Training");
|
b.Navigation("Training");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||||
|
.WithOne()
|
||||||
|
.HasForeignKey("Pf2eModel.Model.Structure.Rule", "Id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_rules_entities_id");
|
||||||
|
|
||||||
|
b.HasOne("Pf2eModel.Model.Structure.Rule", "Parent")
|
||||||
|
.WithMany("Children")
|
||||||
|
.HasForeignKey("ParentId")
|
||||||
|
.HasConstraintName("fk_rules_rules_parent_id");
|
||||||
|
|
||||||
|
b.Navigation("Entity");
|
||||||
|
|
||||||
|
b.Navigation("Parent");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||||
@@ -2426,6 +2476,11 @@ namespace Pf2eModel.Migrations
|
|||||||
b.Navigation("Checks");
|
b.Navigation("Checks");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Children");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("SpellAreas");
|
b.Navigation("SpellAreas");
|
||||||
+34
-1
@@ -24,7 +24,7 @@ namespace Pf2eModel.Migrations
|
|||||||
.Annotation("Npgsql:Enum:deity_fonts", "none,heal,harm,any")
|
.Annotation("Npgsql:Enum:deity_fonts", "none,heal,harm,any")
|
||||||
.Annotation("Npgsql:Enum:deity_sanctification", "holy,unholy,any")
|
.Annotation("Npgsql:Enum:deity_sanctification", "holy,unholy,any")
|
||||||
.Annotation("Npgsql:Enum:entity_rarity", "common,uncommon,rare,unique")
|
.Annotation("Npgsql:Enum:entity_rarity", "common,uncommon,rare,unique")
|
||||||
.Annotation("Npgsql:Enum:entity_type", "unknown,trait,action,ancestry,archetype,background,backpack,campaign_feature,class,subclass_group,subclass,condition,deity,feat,heritage,spell,ritual,language")
|
.Annotation("Npgsql:Enum:entity_type", "unknown,trait,action,ancestry,archetype,background,backpack,campaign_feature,class,subclass_group,subclass,condition,deity,feat,heritage,spell,ritual,language,rule")
|
||||||
.Annotation("Npgsql:Enum:feat_action_type", "passive,action,reaction,free")
|
.Annotation("Npgsql:Enum:feat_action_type", "passive,action,reaction,free")
|
||||||
.Annotation("Npgsql:Enum:feat_category", "uncategorized,ancestry-feature,class-feature,calling,class,skill,general,ancestry,bonus,deityboon,curse,pfsboon,campaign-feature")
|
.Annotation("Npgsql:Enum:feat_category", "uncategorized,ancestry-feature,class-feature,calling,class,skill,general,ancestry,bonus,deityboon,curse,pfsboon,campaign-feature")
|
||||||
.Annotation("Npgsql:Enum:locale_type", "english,legacy_english,russian,legacy,hobby,other")
|
.Annotation("Npgsql:Enum:locale_type", "english,legacy_english,russian,legacy,hobby,other")
|
||||||
@@ -324,6 +324,31 @@ namespace Pf2eModel.Migrations
|
|||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "rules",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
order = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
parent_id = table.Column<int>(type: "integer", nullable: true),
|
||||||
|
breadcrumbs = table.Column<string[]>(type: "text[]", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_rules", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_rules_entities_id",
|
||||||
|
column: x => x.id,
|
||||||
|
principalTable: "entities",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_rules_rules_parent_id",
|
||||||
|
column: x => x.parent_id,
|
||||||
|
principalTable: "rules",
|
||||||
|
principalColumn: "id");
|
||||||
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "spells",
|
name: "spells",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
@@ -1275,6 +1300,11 @@ namespace Pf2eModel.Migrations
|
|||||||
table: "ritual_checks",
|
table: "ritual_checks",
|
||||||
column: "training_id");
|
column: "training_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_rules_parent_id",
|
||||||
|
table: "rules",
|
||||||
|
column: "parent_id");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "ix_spell_areas_spell_id",
|
name: "ix_spell_areas_spell_id",
|
||||||
table: "spell_areas",
|
table: "spell_areas",
|
||||||
@@ -1400,6 +1430,9 @@ namespace Pf2eModel.Migrations
|
|||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "ritual_checks");
|
name: "ritual_checks");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "rules");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "spell_areas");
|
name: "spell_areas");
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ namespace Pf2eModel.Migrations
|
|||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_rarity", new[] { "common", "uncommon", "rare", "unique" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_rarity", new[] { "common", "uncommon", "rare", "unique" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "archetype", "background", "backpack", "campaign_feature", "class", "subclass_group", "subclass", "condition", "deity", "feat", "heritage", "spell", "ritual", "language" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "archetype", "background", "backpack", "campaign_feature", "class", "subclass_group", "subclass", "condition", "deity", "feat", "heritage", "spell", "ritual", "language", "rule" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_action_type", new[] { "passive", "action", "reaction", "free" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_action_type", new[] { "passive", "action", "reaction", "free" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_category", new[] { "uncategorized", "ancestry-feature", "class-feature", "calling", "class", "skill", "general", "ancestry", "bonus", "deityboon", "curse", "pfsboon", "campaign-feature" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_category", new[] { "uncategorized", "ancestry-feature", "class-feature", "calling", "class", "skill", "general", "ancestry", "bonus", "deityboon", "curse", "pfsboon", "campaign-feature" });
|
||||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "locale_type", new[] { "english", "legacy_english", "russian", "legacy", "hobby", "other" });
|
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "locale_type", new[] { "english", "legacy_english", "russian", "legacy", "hobby", "other" });
|
||||||
@@ -1392,6 +1392,37 @@ namespace Pf2eModel.Migrations
|
|||||||
b.ToTable("ritual_checks", (string)null);
|
b.ToTable("ritual_checks", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasColumnOrder(1);
|
||||||
|
|
||||||
|
b.PrimitiveCollection<string[]>("Breadcrumbs")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text[]")
|
||||||
|
.HasColumnName("breadcrumbs");
|
||||||
|
|
||||||
|
b.Property<int>("Order")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("order")
|
||||||
|
.HasColumnOrder(2);
|
||||||
|
|
||||||
|
b.Property<int?>("ParentId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("parent_id")
|
||||||
|
.HasColumnOrder(3);
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_rules");
|
||||||
|
|
||||||
|
b.HasIndex("ParentId")
|
||||||
|
.HasDatabaseName("ix_rules_parent_id");
|
||||||
|
|
||||||
|
b.ToTable("rules", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -2246,6 +2277,25 @@ namespace Pf2eModel.Migrations
|
|||||||
b.Navigation("Training");
|
b.Navigation("Training");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||||
|
.WithOne()
|
||||||
|
.HasForeignKey("Pf2eModel.Model.Structure.Rule", "Id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_rules_entities_id");
|
||||||
|
|
||||||
|
b.HasOne("Pf2eModel.Model.Structure.Rule", "Parent")
|
||||||
|
.WithMany("Children")
|
||||||
|
.HasForeignKey("ParentId")
|
||||||
|
.HasConstraintName("fk_rules_rules_parent_id");
|
||||||
|
|
||||||
|
b.Navigation("Entity");
|
||||||
|
|
||||||
|
b.Navigation("Parent");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||||
@@ -2423,6 +2473,11 @@ namespace Pf2eModel.Migrations
|
|||||||
b.Navigation("Checks");
|
b.Navigation("Checks");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Children");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("SpellAreas");
|
b.Navigation("SpellAreas");
|
||||||
|
|||||||
@@ -57,4 +57,7 @@ public enum EntityType
|
|||||||
|
|
||||||
[PgName("language")]
|
[PgName("language")]
|
||||||
Language,
|
Language,
|
||||||
|
|
||||||
|
[PgName("rule")]
|
||||||
|
Rule,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using Pf2eModel.Model.Base;
|
||||||
|
using Pf2eModel.Model.Enum;
|
||||||
|
|
||||||
|
namespace Pf2eModel.Model.Structure;
|
||||||
|
|
||||||
|
[EntityOfType(EntityType.Rule)]
|
||||||
|
public class Rule : IEntity
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.None)]
|
||||||
|
[Column(Order = 1)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public Entity Entity { get; set; } = null!;
|
||||||
|
|
||||||
|
[Column(Order = 2)]
|
||||||
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
[Column(Order = 3)]
|
||||||
|
public int? ParentId { get; set; } = null;
|
||||||
|
|
||||||
|
public Rule? Parent { get; set; } = null;
|
||||||
|
|
||||||
|
public ICollection<Rule> Children { get; set; } = [];
|
||||||
|
|
||||||
|
public string[] Breadcrumbs { get; set; } = [];
|
||||||
|
}
|
||||||
@@ -100,6 +100,8 @@ public partial class Pf2eDbContext : DbContext
|
|||||||
|
|
||||||
public virtual DbSet<RitualCheck> RitualChecks { get; set; }
|
public virtual DbSet<RitualCheck> RitualChecks { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Rule> Rules { get; set; }
|
||||||
|
|
||||||
public virtual DbSet<Source> Sources { get; set; }
|
public virtual DbSet<Source> Sources { get; set; }
|
||||||
|
|
||||||
public virtual DbSet<Spell> Spells { get; set; }
|
public virtual DbSet<Spell> Spells { get; set; }
|
||||||
|
|||||||
@@ -503,6 +503,18 @@ public partial class Pf2eDbContext
|
|||||||
{
|
{
|
||||||
BindEntity(entity);
|
BindEntity(entity);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Rule
|
||||||
|
modelBuilder.Entity<Rule>(entity =>
|
||||||
|
{
|
||||||
|
BindEntity(entity);
|
||||||
|
|
||||||
|
entity
|
||||||
|
.HasOne(r => r.Parent)
|
||||||
|
.WithMany(r => r.Children)
|
||||||
|
.HasForeignKey(r => r.ParentId)
|
||||||
|
.IsRequired(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DefineMethods(ModelBuilder modelBuilder)
|
private void DefineMethods(ModelBuilder modelBuilder)
|
||||||
|
|||||||
Reference in New Issue
Block a user