Tabellenstruktur im Code Migrationen im Code
redundanzen entfernt und zusatzinfos (Quelle) integriert
This commit is contained in:
@@ -0,0 +1,349 @@
|
||||
package gsmaster
|
||||
|
||||
import (
|
||||
"bamort/database"
|
||||
"bamort/models"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
// EnhanceLearningDataWithExistingTables ergänzt die neuen Lernkosten-Tabellen mit Daten aus den bereits vorhandenen Tabellen
|
||||
func EnhanceLearningDataWithExistingTables() error {
|
||||
log.Println("Starting enhancement of learning data with existing tables...")
|
||||
|
||||
// 1. Fertigkeiten aus der bestehenden Skill-Tabelle in SkillCategoryDifficulty einbinden
|
||||
if err := linkExistingSkillsToCategories(); err != nil {
|
||||
return fmt.Errorf("failed to link existing skills to categories: %w", err)
|
||||
}
|
||||
|
||||
// 2. Zauber aus der bestehenden Spell-Tabelle mit Zauberschulen verknüpfen
|
||||
if err := linkExistingSpellsToSchools(); err != nil {
|
||||
return fmt.Errorf("failed to link existing spells to schools: %w", err)
|
||||
}
|
||||
|
||||
// 3. Charaktere aus der bestehenden Character-Tabelle mit Charakterklassen verknüpfen
|
||||
if err := linkExistingCharactersToClasses(); err != nil {
|
||||
return fmt.Errorf("failed to link existing characters to classes: %w", err)
|
||||
}
|
||||
|
||||
// 4. Fehlende Fertigkeiten aus der bestehenden Tabelle zu den Kategorien hinzufügen
|
||||
if err := addMissingSkillsToCategories(); err != nil {
|
||||
return fmt.Errorf("failed to add missing skills to categories: %w", err)
|
||||
}
|
||||
|
||||
// 5. Verknüpfe bestehende Fertigkeiten und Zauber mit Standardquellen
|
||||
if err := linkExistingItemsToDefaultSources(); err != nil {
|
||||
return fmt.Errorf("failed to link existing items to default sources: %w", err)
|
||||
}
|
||||
|
||||
log.Println("Enhancement completed successfully!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// linkExistingSkillsToCategories verknüpft vorhandene Fertigkeiten mit Kategorien und Schwierigkeiten
|
||||
func linkExistingSkillsToCategories() error {
|
||||
var skills []models.Skill
|
||||
if err := database.DB.Find(&skills).Error; err != nil {
|
||||
return fmt.Errorf("failed to fetch existing skills: %w", err)
|
||||
}
|
||||
|
||||
for _, skill := range skills {
|
||||
// Prüfe ob bereits Verknüpfungen für diese Fertigkeit existieren
|
||||
var existingLinks []models.SkillCategoryDifficulty
|
||||
if err := database.DB.Where("skill_id = ?", skill.ID).Find(&existingLinks).Error; err != nil {
|
||||
return fmt.Errorf("failed to check existing links for skill %s: %w", skill.Name, err)
|
||||
}
|
||||
|
||||
// Wenn bereits Verknüpfungen existieren, überspringe
|
||||
if len(existingLinks) > 0 {
|
||||
log.Printf("Skill %s already has category links, skipping", skill.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// Suche nach der Fertigkeit in den lerningCostsData
|
||||
category, difficulty := findSkillInLearningData(skill.Name)
|
||||
if category == "" {
|
||||
log.Printf("Warning: Skill %s not found in learning data, using default category", skill.Name)
|
||||
// Verwende eine Standard-Kategorie basierend auf der bestehenden Category
|
||||
if skill.Category != "" {
|
||||
category = skill.Category
|
||||
difficulty = skill.Difficulty
|
||||
if difficulty == "" {
|
||||
difficulty = "normal"
|
||||
}
|
||||
} else {
|
||||
category = "Unbekannt"
|
||||
difficulty = "normal"
|
||||
}
|
||||
}
|
||||
|
||||
// Erstelle Verknüpfung
|
||||
if err := createSkillCategoryLink(skill.ID, skill.Name, category, difficulty); err != nil {
|
||||
log.Printf("Warning: Failed to create category link for skill %s: %v", skill.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// linkExistingSpellsToSchools verknüpft vorhandene Zauber mit Zauberschulen
|
||||
func linkExistingSpellsToSchools() error {
|
||||
var spells []models.Spell
|
||||
if err := database.DB.Find(&spells).Error; err != nil {
|
||||
return fmt.Errorf("failed to fetch existing spells: %w", err)
|
||||
}
|
||||
|
||||
for _, spell := range spells {
|
||||
// Prüfe ob die Zauberschule existiert
|
||||
if spell.Category == "" {
|
||||
log.Printf("Warning: Spell %s has no category, skipping", spell.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
var spellSchool models.SpellSchool
|
||||
if err := spellSchool.FirstByName(spell.Category); err != nil {
|
||||
// Zauberschule existiert nicht, erstelle sie
|
||||
newSchool := models.SpellSchool{
|
||||
Name: spell.Category,
|
||||
GameSystem: "midgard",
|
||||
}
|
||||
if err := newSchool.Create(); err != nil {
|
||||
log.Printf("Warning: Failed to create spell school %s for spell %s: %v", spell.Category, spell.Name, err)
|
||||
continue
|
||||
}
|
||||
log.Printf("Created new spell school: %s", spell.Category)
|
||||
}
|
||||
|
||||
log.Printf("Spell %s linked to school %s", spell.Name, spell.Category)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// linkExistingCharactersToClasses verknüpft vorhandene Charaktere mit Charakterklassen
|
||||
func linkExistingCharactersToClasses() error {
|
||||
var characters []models.Char
|
||||
if err := database.DB.Find(&characters).Error; err != nil {
|
||||
return fmt.Errorf("failed to fetch existing characters: %w", err)
|
||||
}
|
||||
|
||||
// Lade alle verfügbaren Charakterklassen aus der Datenbank
|
||||
var characterClasses []models.CharacterClass
|
||||
if err := database.DB.Find(&characterClasses).Error; err != nil {
|
||||
return fmt.Errorf("failed to fetch character classes from database: %w", err)
|
||||
}
|
||||
|
||||
// Erstelle Mapping-Maps für beide Richtungen (Code->Klasse und Name->Klasse)
|
||||
codeToClass := make(map[string]models.CharacterClass)
|
||||
nameToClass := make(map[string]models.CharacterClass)
|
||||
|
||||
for _, class := range characterClasses {
|
||||
codeToClass[class.Code] = class
|
||||
nameToClass[class.Name] = class
|
||||
}
|
||||
|
||||
for _, character := range characters {
|
||||
var characterClass models.CharacterClass
|
||||
var found bool
|
||||
|
||||
// Versuche zuerst über Code zu finden (falls character.Typ bereits ein Code ist)
|
||||
if class, exists := codeToClass[character.Typ]; exists {
|
||||
characterClass = class
|
||||
found = true
|
||||
} else if class, exists := nameToClass[character.Typ]; exists {
|
||||
// Wenn nicht über Code gefunden, versuche über vollständigen Namen
|
||||
characterClass = class
|
||||
found = true
|
||||
}
|
||||
|
||||
if !found {
|
||||
log.Printf("Warning: Character class '%s' not found in database for character %s", character.Typ, character.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("Character %s linked to class %s (%s)", character.Name, characterClass.Code, characterClass.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// addMissingSkillsToCategories fügt Fertigkeiten hinzu, die in der Datenbank existieren aber nicht in den Lernkosten-Daten
|
||||
func addMissingSkillsToCategories() error {
|
||||
var skills []models.Skill
|
||||
if err := database.DB.Find(&skills).Error; err != nil {
|
||||
return fmt.Errorf("failed to fetch skills: %w", err)
|
||||
}
|
||||
|
||||
for _, skill := range skills {
|
||||
// Prüfe ob bereits Kategorien-Verknüpfungen existieren
|
||||
var count int64
|
||||
if err := database.DB.Model(&models.SkillCategoryDifficulty{}).Where("skill_id = ?", skill.ID).Count(&count).Error; err != nil {
|
||||
return fmt.Errorf("failed to count category links for skill %s: %w", skill.Name, err)
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
// Keine Kategorien-Verknüpfung gefunden, erstelle eine Standard-Verknüpfung
|
||||
category := "Unbekannt"
|
||||
difficulty := "normal"
|
||||
|
||||
// Verwende bestehende Kategorie falls vorhanden
|
||||
if skill.Category != "" {
|
||||
category = skill.Category
|
||||
}
|
||||
if skill.Difficulty != "" {
|
||||
difficulty = skill.Difficulty
|
||||
}
|
||||
|
||||
if err := createSkillCategoryLink(skill.ID, skill.Name, category, difficulty); err != nil {
|
||||
log.Printf("Warning: Failed to create default category link for skill %s: %v", skill.Name, err)
|
||||
} else {
|
||||
log.Printf("Created default category link for skill %s: %s - %s", skill.Name, category, difficulty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Hilfsfunktionen
|
||||
|
||||
// findSkillInLearningData sucht eine Fertigkeit in den learningCostsData und gibt Kategorie und Schwierigkeit zurück
|
||||
func findSkillInLearningData(skillName string) (string, string) {
|
||||
for categoryName, difficulties := range learningCostsData.ImprovementCost {
|
||||
for difficultyName, data := range difficulties {
|
||||
for _, skill := range data.Skills {
|
||||
if skill == skillName {
|
||||
return categoryName, difficultyName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", ""
|
||||
}
|
||||
|
||||
// createSkillCategoryLink erstellt eine Verknüpfung zwischen Fertigkeit, Kategorie und Schwierigkeit
|
||||
func createSkillCategoryLink(skillID uint, skillName, categoryName, difficultyName string) error {
|
||||
// Hole oder erstelle die Kategorie
|
||||
var skillCategory models.SkillCategory
|
||||
if err := skillCategory.FirstByName(categoryName); err != nil {
|
||||
// Kategorie existiert nicht, erstelle sie
|
||||
skillCategory = models.SkillCategory{
|
||||
Name: categoryName,
|
||||
GameSystem: "midgard",
|
||||
}
|
||||
if err := skillCategory.Create(); err != nil {
|
||||
return fmt.Errorf("failed to create skill category %s: %w", categoryName, err)
|
||||
}
|
||||
log.Printf("Created new skill category: %s", categoryName)
|
||||
}
|
||||
|
||||
// Hole oder erstelle die Schwierigkeit
|
||||
var skillDifficulty models.SkillDifficulty
|
||||
if err := skillDifficulty.FirstByName(difficultyName); err != nil {
|
||||
// Schwierigkeit existiert nicht, erstelle sie
|
||||
skillDifficulty = models.SkillDifficulty{
|
||||
Name: difficultyName,
|
||||
GameSystem: "midgard",
|
||||
}
|
||||
if err := skillDifficulty.Create(); err != nil {
|
||||
return fmt.Errorf("failed to create skill difficulty %s: %w", difficultyName, err)
|
||||
}
|
||||
log.Printf("Created new skill difficulty: %s", difficultyName)
|
||||
}
|
||||
|
||||
// Bestimme LearnCost basierend auf den learningCostsData
|
||||
learnCost := 2 // Standard-Wert
|
||||
if categoryData, exists := learningCostsData.ImprovementCost[categoryName]; exists {
|
||||
if difficultyData, exists := categoryData[difficultyName]; exists {
|
||||
learnCost = difficultyData.LearnCost
|
||||
}
|
||||
}
|
||||
|
||||
// Erstelle die Verknüpfung
|
||||
categoryDifficulty := models.SkillCategoryDifficulty{
|
||||
SkillID: skillID,
|
||||
SkillCategoryID: skillCategory.ID,
|
||||
SkillDifficultyID: skillDifficulty.ID,
|
||||
LearnCost: learnCost,
|
||||
}
|
||||
|
||||
if err := categoryDifficulty.Create(); err != nil {
|
||||
return fmt.Errorf("failed to create skill category difficulty link: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("Created skill category link: %s - %s - %s (Learn: %d LE)", skillName, categoryName, difficultyName, learnCost)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateLearningCostsTables erstellt alle neuen Tabellen für das Lernkosten-System
|
||||
func CreateLearningCostsTables() error {
|
||||
log.Println("Creating learning costs tables...")
|
||||
|
||||
// Liste aller neuen Modelle
|
||||
models := []interface{}{
|
||||
&models.Source{},
|
||||
&models.CharacterClass{},
|
||||
&models.SkillCategory{},
|
||||
&models.SkillDifficulty{},
|
||||
&models.SpellSchool{},
|
||||
&models.ClassCategoryEPCost{},
|
||||
&models.ClassSpellSchoolEPCost{},
|
||||
&models.SpellLevelLECost{},
|
||||
&models.SkillCategoryDifficulty{},
|
||||
&models.SkillImprovementCost{},
|
||||
}
|
||||
|
||||
// Erstelle oder migriere alle Tabellen
|
||||
for _, model := range models {
|
||||
if err := database.DB.AutoMigrate(model); err != nil {
|
||||
return fmt.Errorf("failed to migrate table for model %T: %w", model, err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Learning costs tables created successfully!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// linkExistingItemsToDefaultSources verknüpft bestehende Fertigkeiten und Zauber mit Standardquellen
|
||||
func linkExistingItemsToDefaultSources() error {
|
||||
// Hole die Standardquellen
|
||||
var kodSource models.Source
|
||||
if err := kodSource.FirstByCode("KOD"); err != nil {
|
||||
return fmt.Errorf("KOD source not found: %w", err)
|
||||
}
|
||||
|
||||
var arkSource models.Source
|
||||
if err := arkSource.FirstByCode("ARK"); err != nil {
|
||||
return fmt.Errorf("ARK source not found: %w", err)
|
||||
}
|
||||
|
||||
// Verknüpfe Fertigkeiten mit KOD (falls noch keine Quelle zugeordnet)
|
||||
var skills []models.Skill
|
||||
if err := database.DB.Where("source_id IS NULL OR source_id = 0").Find(&skills).Error; err != nil {
|
||||
return fmt.Errorf("failed to fetch skills without source: %w", err)
|
||||
}
|
||||
|
||||
for _, skill := range skills {
|
||||
if err := database.DB.Model(&skill).Update("source_id", kodSource.ID).Error; err != nil {
|
||||
log.Printf("Warning: Failed to update source for skill %s: %v", skill.Name, err)
|
||||
} else {
|
||||
log.Printf("Linked skill %s to source KOD", skill.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Verknüpfe Zauber mit ARK (falls noch keine Quelle zugeordnet)
|
||||
var spells []models.Spell
|
||||
if err := database.DB.Where("source_id IS NULL OR source_id = 0").Find(&spells).Error; err != nil {
|
||||
return fmt.Errorf("failed to fetch spells without source: %w", err)
|
||||
}
|
||||
|
||||
for _, spell := range spells {
|
||||
if err := database.DB.Model(&spell).Update("source_id", arkSource.ID).Error; err != nil {
|
||||
log.Printf("Warning: Failed to update source for spell %s: %v", spell.Name, err)
|
||||
} else {
|
||||
log.Printf("Linked spell %s to source ARK", spell.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user