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_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_member = true
|
||||
|
||||
|
||||
@@ -3,29 +3,35 @@
|
||||
namespace Pf2eDataScrapper.Importers;
|
||||
|
||||
/// <summary>
|
||||
/// Абстрактный класс импортёра
|
||||
/// Абстрактный класс импортёра.
|
||||
/// </summary>
|
||||
internal abstract class AbstractImporter
|
||||
{
|
||||
/// <summary>
|
||||
/// Отображаемое имя импортёра
|
||||
/// Отображаемое имя импортёра.
|
||||
/// </summary>
|
||||
public abstract string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Короткое имя импортёра
|
||||
/// Короткое имя импортёра.
|
||||
/// </summary>
|
||||
public abstract string Slug { get; }
|
||||
|
||||
public abstract AbstractImporterRepository Repository { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Путь к директории с данными для импортёра
|
||||
/// Путь к директории с данными для импортёра.
|
||||
/// </summary>
|
||||
public string Dir => Path.Combine(EnvSettings.DataDirPath, Slug);
|
||||
|
||||
/// <summary>
|
||||
/// Метод подготовки данных для импорта
|
||||
/// Перечисление процессоров, которые будут использоваться для обработки данных.
|
||||
/// При пустом массиве будут обработаны все доступные процессоры.
|
||||
/// </summary>
|
||||
public string[] ProcessorNames { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Метод подготовки данных для импорта.
|
||||
/// </summary>
|
||||
public abstract void Prepare();
|
||||
|
||||
@@ -35,7 +41,7 @@ internal abstract class AbstractImporter
|
||||
public abstract void Import();
|
||||
|
||||
/// <summary>
|
||||
/// Построение схем данных
|
||||
/// Построение схем данных.
|
||||
/// </summary>
|
||||
public abstract void BuildSchemas();
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ internal class AonprdImporter : AbstractImporter
|
||||
public override void Import()
|
||||
{
|
||||
AonprdDataBuilder builder = new(Loader);
|
||||
builder.Processors.UseOnlyNames(ProcessorNames);
|
||||
|
||||
builder.TruncateTables();
|
||||
builder.Build();
|
||||
|
||||
+29
-1
@@ -14,7 +14,9 @@ internal class AonprdProcessorCollection
|
||||
public int Priority = -1;
|
||||
}
|
||||
|
||||
public readonly List<ProcessorItem> Items = [];
|
||||
private readonly List<ProcessorItem> _allItems;
|
||||
|
||||
public List<ProcessorItem> Items { get; private set; } = [];
|
||||
|
||||
public AonprdProcessorCollection()
|
||||
{
|
||||
@@ -50,6 +52,8 @@ internal class AonprdProcessorCollection
|
||||
|
||||
Items.Add(new(attribute, constructor));
|
||||
}
|
||||
|
||||
_allItems = Items.ToList();
|
||||
}
|
||||
|
||||
private void CheckDependencies()
|
||||
@@ -109,4 +113,28 @@ internal class AonprdProcessorCollection
|
||||
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();
|
||||
|
||||
Match match = MarkdownRegex().Match(input);
|
||||
Match match = LinkRegex().Match(input);
|
||||
if (match.Captures.Count > 0)
|
||||
{
|
||||
result.Links.Add(
|
||||
@@ -34,7 +34,7 @@ internal partial class StringHelper
|
||||
);
|
||||
}
|
||||
|
||||
result.Suffix = MarkdownRegex().Replace(input, "");
|
||||
result.Suffix = LinkRegex().Replace(input, "");
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -51,7 +51,7 @@ internal partial class StringHelper
|
||||
public static partial Regex SourceSuffixRegex();
|
||||
|
||||
[GeneratedRegex(@"(.*?)\[(.*?)\]\((.*?)\)")]
|
||||
public static partial Regex MarkdownRegex();
|
||||
public static partial Regex LinkRegex();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
-63
@@ -29,18 +29,17 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
||||
{
|
||||
if (Input.GetOptional<JArray>("remaster_id") is not null)
|
||||
{
|
||||
string id = Input.GetRequired<string>("id");
|
||||
string name = Input.GetRequired<string>("name");
|
||||
|
||||
ProcessLegacy(id, name);
|
||||
throw new LegacyItemException(name);
|
||||
LegacyEntityHandler handler = new(this);
|
||||
LegacyHandlers.Add(handler);
|
||||
throw new LegacyItemException(handler.LegacyName);
|
||||
}
|
||||
|
||||
AddEntity();
|
||||
AddAlias();
|
||||
AddSource();
|
||||
AddExternal();
|
||||
AddTraits();
|
||||
|
||||
ProcessLegacy();
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
@@ -49,6 +48,8 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
||||
Context.SaveChanges();
|
||||
}
|
||||
|
||||
// Description generation
|
||||
|
||||
protected virtual string[] AddedDescriptionPaths() => [];
|
||||
|
||||
protected string AddedDescription(string path) =>
|
||||
@@ -60,6 +61,8 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
||||
protected virtual string GetDescription() =>
|
||||
Input.GetRequired<string>("markdown") + AddedDescription(AddedDescriptionPaths());
|
||||
|
||||
// Entity generation
|
||||
|
||||
protected virtual void AddEntity()
|
||||
{
|
||||
Entity.Id = Helper.NextEntityId;
|
||||
@@ -78,57 +81,12 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
||||
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()
|
||||
{
|
||||
string name = Input.GetRequired<string>("source[0]");
|
||||
|
||||
Source? source = Context.Sources.FirstOrDefault(s => s.Name == name);
|
||||
|
||||
if (source == null)
|
||||
foreach (EntitySource entitySource in GetSources())
|
||||
{
|
||||
source = new()
|
||||
{
|
||||
Name = name,
|
||||
Category = Input.EnumRequired<SourceCategory>("primary_source_category"),
|
||||
ReleaseDate = DateOnly.Parse(Input.GetRequired<string>("release_date")),
|
||||
};
|
||||
|
||||
Context.Sources.Add(source);
|
||||
Entity.Sources.Add(entitySource);
|
||||
}
|
||||
|
||||
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()
|
||||
@@ -179,20 +137,76 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
||||
}
|
||||
}
|
||||
|
||||
protected void ProcessLegacy(string id, string name)
|
||||
protected virtual void ProcessLegacy()
|
||||
{
|
||||
if (RemasterWithoutLegacy.TryGetValue(id, out Entity? remastered))
|
||||
{
|
||||
// if (remastered.ToString() != name)
|
||||
remastered.Name[LocaleType.LegacyEnglish] = name;
|
||||
JArray? legacyIdArray = Input.GetOptional<JArray>("legacy_id");
|
||||
|
||||
RemasterWithoutLegacy.Remove(id);
|
||||
if (legacyIdArray is null)
|
||||
{
|
||||
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
|
||||
{
|
||||
LegacyAliases.Add(id, name);
|
||||
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)
|
||||
{
|
||||
@@ -214,9 +228,7 @@ internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
||||
return isLowercase ? hash.ToLower() : hash;
|
||||
}
|
||||
|
||||
protected static readonly Dictionary<string, string> LegacyAliases = [];
|
||||
|
||||
protected static readonly Dictionary<string, Entity> RemasterWithoutLegacy = [];
|
||||
protected static readonly List<LegacyEntityHandler> LegacyHandlers = [];
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
private bool _skipping = false;
|
||||
|
||||
public override void Add()
|
||||
{
|
||||
if (!_skipping)
|
||||
{
|
||||
Context.Actions.Add(Object);
|
||||
}
|
||||
}
|
||||
public override void Add() => Context.Actions.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
if (Input.GetRequired<string>("markdown").StartsWith("**Activate**"))
|
||||
{
|
||||
_skipping = true;
|
||||
return;
|
||||
throw new SkipItemException(Input.GetRequired<string>("name"), "activating action");
|
||||
}
|
||||
|
||||
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("}", ")");
|
||||
|
||||
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();
|
||||
|
||||
importer.ProcessorNames = ["rules"];
|
||||
|
||||
importer.Prepare();
|
||||
importer.Import();
|
||||
// importer.BuildSchemas();
|
||||
|
||||
+57
-2
@@ -13,7 +13,7 @@ using Pf2eModel.Model.Enum;
|
||||
namespace Pf2eModel.Migrations
|
||||
{
|
||||
[DbContext(typeof(Pf2eDbContext))]
|
||||
[Migration("20250506175505_1")]
|
||||
[Migration("20250507112626_1")]
|
||||
partial class _1
|
||||
{
|
||||
/// <inheritdoc />
|
||||
@@ -34,7 +34,7 @@ namespace Pf2eModel.Migrations
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
|
||||
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_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" });
|
||||
@@ -1395,6 +1395,37 @@ namespace Pf2eModel.Migrations
|
||||
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 =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -2249,6 +2280,25 @@ namespace Pf2eModel.Migrations
|
||||
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 =>
|
||||
{
|
||||
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||
@@ -2426,6 +2476,11 @@ namespace Pf2eModel.Migrations
|
||||
b.Navigation("Checks");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b =>
|
||||
{
|
||||
b.Navigation("Children");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||
{
|
||||
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_sanctification", "holy,unholy,any")
|
||||
.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_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")
|
||||
@@ -324,6 +324,31 @@ namespace Pf2eModel.Migrations
|
||||
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(
|
||||
name: "spells",
|
||||
columns: table => new
|
||||
@@ -1275,6 +1300,11 @@ namespace Pf2eModel.Migrations
|
||||
table: "ritual_checks",
|
||||
column: "training_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_rules_parent_id",
|
||||
table: "rules",
|
||||
column: "parent_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_spell_areas_spell_id",
|
||||
table: "spell_areas",
|
||||
@@ -1400,6 +1430,9 @@ namespace Pf2eModel.Migrations
|
||||
migrationBuilder.DropTable(
|
||||
name: "ritual_checks");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "rules");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "spell_areas");
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Pf2eModel.Migrations
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
|
||||
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
|
||||
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_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" });
|
||||
@@ -1392,6 +1392,37 @@ namespace Pf2eModel.Migrations
|
||||
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 =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -2246,6 +2277,25 @@ namespace Pf2eModel.Migrations
|
||||
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 =>
|
||||
{
|
||||
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
|
||||
@@ -2423,6 +2473,11 @@ namespace Pf2eModel.Migrations
|
||||
b.Navigation("Checks");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Rule", b =>
|
||||
{
|
||||
b.Navigation("Children");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Pf2eModel.Model.Structure.Spell", b =>
|
||||
{
|
||||
b.Navigation("SpellAreas");
|
||||
|
||||
@@ -57,4 +57,7 @@ public enum EntityType
|
||||
|
||||
[PgName("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<Rule> Rules { get; set; }
|
||||
|
||||
public virtual DbSet<Source> Sources { get; set; }
|
||||
|
||||
public virtual DbSet<Spell> Spells { get; set; }
|
||||
|
||||
@@ -503,6 +503,18 @@ public partial class Pf2eDbContext
|
||||
{
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user