renamed tables for a name more matching the purpose
This commit is contained in:
@@ -37,6 +37,7 @@
|
|||||||
./backend$ go test ./... -v 2>&1 |grep FAIL
|
./backend$ go test ./... -v 2>&1 |grep FAIL
|
||||||
* API endpunkte für Export/Import aus Commit 2dcb4e00faaf316b98eb28e83cc5137bf0d1385d
|
* API endpunkte für Export/Import aus Commit 2dcb4e00faaf316b98eb28e83cc5137bf0d1385d
|
||||||
* wouldn't it be a good idea to remove the GameSystem from all the records and define it in a kind of manifest. The values in the manifest could be applied to all records (where needed) during the import session. export_import.go
|
* wouldn't it be a good idea to remove the GameSystem from all the records and define it in a kind of manifest. The values in the manifest could be applied to all records (where needed) during the import session. export_import.go
|
||||||
|
* maintanance view for gsm_cc_class_category_points
|
||||||
## Refaktor
|
## Refaktor
|
||||||
|
|
||||||
* Export Import Module neu grupieren
|
* Export Import Module neu grupieren
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ The export/import mechanism allows exporting all master data from the `model_gsm
|
|||||||
## Supported Entities
|
## Supported Entities
|
||||||
|
|
||||||
### From `model_learning_costs.go`:
|
### From `model_learning_costs.go`:
|
||||||
- **Sources** (`learning_sources`) - Game books and source materials
|
- **Sources** (`gsm_lit_sources`) - Game books and source materials
|
||||||
- **SkillCategories** (`learning_skill_categories`) - Skill classification categories
|
- **SkillCategories** (`learning_skill_categories`) - Skill classification categories
|
||||||
- **SkillDifficulties** (`learning_skill_difficulties`) - Difficulty levels
|
- **SkillDifficulties** (`learning_skill_difficulties`) - Difficulty levels
|
||||||
- **SkillCategoryDifficulties** (`learning_skill_category_difficulties`) - Relationship between skills, categories, and difficulties with learning costs
|
- **SkillCategoryDifficulties** (`learning_skill_category_difficulties`) - Relationship between skills, categories, and difficulties with learning costs
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func ValidateLearningCostsData() error {
|
|||||||
query string
|
query string
|
||||||
expected int
|
expected int
|
||||||
}{
|
}{
|
||||||
{"Character Classes", "SELECT COUNT(*) FROM learning_character_classes", 15},
|
{"Character Classes", "SELECT COUNT(*) FROM gsm_character_classes", 15},
|
||||||
{"Skill Categories", "SELECT COUNT(*) FROM learning_skill_categories", 10},
|
{"Skill Categories", "SELECT COUNT(*) FROM learning_skill_categories", 10},
|
||||||
{"Skill Difficulties", "SELECT COUNT(*) FROM learning_skill_difficulties", 4},
|
{"Skill Difficulties", "SELECT COUNT(*) FROM learning_skill_difficulties", 4},
|
||||||
{"Spell Schools", "SELECT COUNT(*) FROM learning_spell_schools", 10},
|
{"Spell Schools", "SELECT COUNT(*) FROM learning_spell_schools", 10},
|
||||||
@@ -70,7 +70,7 @@ func GetLearningCostsSummary() (map[string]interface{}, error) {
|
|||||||
|
|
||||||
// Zähle Einträge in verschiedenen Tabellen
|
// Zähle Einträge in verschiedenen Tabellen
|
||||||
tables := []string{
|
tables := []string{
|
||||||
"learning_character_classes",
|
"gsm_character_classes",
|
||||||
"learning_skill_categories",
|
"learning_skill_categories",
|
||||||
"learning_skill_difficulties",
|
"learning_skill_difficulties",
|
||||||
"learning_spell_schools",
|
"learning_spell_schools",
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ func copyMariaDBToSQLite(mariaDB, sqliteDB *gorm.DB) error {
|
|||||||
&models.SkillCategoryDifficulty{},
|
&models.SkillCategoryDifficulty{},
|
||||||
&models.WeaponSkillCategoryDifficulty{},
|
&models.WeaponSkillCategoryDifficulty{},
|
||||||
&models.SkillImprovementCost{},
|
&models.SkillImprovementCost{},
|
||||||
&models.ClassLearningPoints{},
|
&models.ClassCategoryLearningPoints{},
|
||||||
&models.ClassSpellPoints{},
|
&models.ClassSpellPoints{},
|
||||||
&models.ClassTypicalSkill{},
|
&models.ClassTypicalSkill{},
|
||||||
&models.ClassTypicalSpell{},
|
&models.ClassTypicalSpell{},
|
||||||
@@ -330,25 +330,24 @@ func copyTableData(sourceDB, targetDB *gorm.DB, model interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the actual records from reflection
|
// Get the records for iteration
|
||||||
records := recordsPtr.Elem().Interface()
|
recordsVal := recordsPtr.Elem()
|
||||||
recordsLen := recordsPtr.Elem().Len()
|
if recordsVal.Len() == 0 {
|
||||||
|
|
||||||
if recordsLen == 0 {
|
|
||||||
logger.Debug("Keine weiteren Datensätze für %s", tableName)
|
logger.Debug("Keine weiteren Datensätze für %s", tableName)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Batch in SQLite einfügen mit Konflikt-Behandlung
|
// Batch in SQLite einfügen
|
||||||
// Verwende Clauses.OnConflict um bestehende Datensätze zu ersetzen
|
// Use Save() instead of Create() to avoid GORM applying default values to zero values (e.g., false for booleans)
|
||||||
if err := targetDB.Model(model).Clauses(clause.OnConflict{
|
for i := 0; i < recordsVal.Len(); i++ {
|
||||||
UpdateAll: true,
|
record := recordsVal.Index(i).Addr().Interface()
|
||||||
}).Create(records).Error; err != nil {
|
if err := targetDB.Save(record).Error; err != nil {
|
||||||
logger.Error("Fehler beim Einfügen von Batch %d für %s: %s", batchNum, tableName, err.Error())
|
logger.Error("Fehler beim Speichern von Datensatz in Batch %d für %s: %s", batchNum, tableName, err.Error())
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug("Batch %d/%d für %s erfolgreich kopiert (%d Datensätze)", batchNum, totalBatches, tableName, recordsLen)
|
logger.Debug("Batch %d/%d für %s erfolgreich kopiert (%d Datensätze)", batchNum, totalBatches, tableName, recordsVal.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Tabelle %s erfolgreich kopiert (%d Datensätze total)", tableName, count)
|
logger.Info("Tabelle %s erfolgreich kopiert (%d Datensätze total)", tableName, count)
|
||||||
@@ -755,7 +754,7 @@ func copySQLiteToMariaDB(sqliteDB, mariaDB *gorm.DB) error {
|
|||||||
&models.SkillCategoryDifficulty{}, // Jetzt nach Skills
|
&models.SkillCategoryDifficulty{}, // Jetzt nach Skills
|
||||||
&models.WeaponSkillCategoryDifficulty{},
|
&models.WeaponSkillCategoryDifficulty{},
|
||||||
&models.SkillImprovementCost{},
|
&models.SkillImprovementCost{},
|
||||||
&models.ClassLearningPoints{},
|
&models.ClassCategoryLearningPoints{},
|
||||||
&models.ClassSpellPoints{},
|
&models.ClassSpellPoints{},
|
||||||
&models.ClassTypicalSkill{},
|
&models.ClassTypicalSkill{},
|
||||||
&models.ClassTypicalSpell{},
|
&models.ClassTypicalSpell{},
|
||||||
@@ -913,8 +912,8 @@ func copyTableDataReverse(sourceDB, targetDB *gorm.DB, model interface{}) error
|
|||||||
return fmt.Errorf("failed to read batch from source: %w", err)
|
return fmt.Errorf("failed to read batch from source: %w", err)
|
||||||
}
|
}
|
||||||
records = batch
|
records = batch
|
||||||
case *models.ClassLearningPoints:
|
case *models.ClassCategoryLearningPoints:
|
||||||
var batch []models.ClassLearningPoints
|
var batch []models.ClassCategoryLearningPoints
|
||||||
if err := sourceDB.Limit(batchSize).Offset(offset).Find(&batch).Error; err != nil {
|
if err := sourceDB.Limit(batchSize).Offset(offset).Find(&batch).Error; err != nil {
|
||||||
return fmt.Errorf("failed to read batch from source: %w", err)
|
return fmt.Errorf("failed to read batch from source: %w", err)
|
||||||
}
|
}
|
||||||
@@ -1155,7 +1154,7 @@ func clearMariaDBData(db *gorm.DB) error {
|
|||||||
&models.ClassTypicalSpell{},
|
&models.ClassTypicalSpell{},
|
||||||
&models.ClassTypicalSkill{},
|
&models.ClassTypicalSkill{},
|
||||||
&models.ClassSpellPoints{},
|
&models.ClassSpellPoints{},
|
||||||
&models.ClassLearningPoints{},
|
&models.ClassCategoryLearningPoints{},
|
||||||
|
|
||||||
// GSMaster Basis-Daten
|
// GSMaster Basis-Daten
|
||||||
&models.Believe{},
|
&models.Believe{},
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
package maintenance
|
package maintenance
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bamort/database"
|
||||||
"bamort/models"
|
"bamort/models"
|
||||||
"bamort/user"
|
"bamort/user"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"gorm.io/driver/sqlite"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestTableListCompleteness verifies that all database models are included in the table lists
|
// TestTableListCompleteness verifies that all database models are included in the table lists
|
||||||
@@ -136,6 +142,139 @@ func TestTableListCompleteness(t *testing.T) {
|
|||||||
t.Logf("Total expected models: %d", len(expectedModels))
|
t.Logf("Total expected models: %d", len(expectedModels))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestImprovableFieldTransfer tests that the Improvable field is correctly transferred from MariaDB to SQLite
|
||||||
|
func TestImprovableFieldTransfer(t *testing.T) {
|
||||||
|
setupTestEnvironment(t)
|
||||||
|
|
||||||
|
// Create source database (simulating MariaDB)
|
||||||
|
sourceDB, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Create target database (simulating SQLite)
|
||||||
|
targetDB, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Migrate structures
|
||||||
|
err = sourceDB.AutoMigrate(&models.Skill{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = targetDB.AutoMigrate(&models.Skill{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Insert test data with different Improvable values
|
||||||
|
// Use raw SQL to avoid GORM applying default values
|
||||||
|
testSkills := []struct {
|
||||||
|
ID uint
|
||||||
|
Name string
|
||||||
|
GameSystem string
|
||||||
|
Improvable bool
|
||||||
|
InnateSkill bool
|
||||||
|
}{
|
||||||
|
{1, "Hören", "midgard", false, true},
|
||||||
|
{2, "Alchimie", "midgard", true, false},
|
||||||
|
{3, "Nachtsicht", "midgard", false, true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, skill := range testSkills {
|
||||||
|
err = sourceDB.Exec(`INSERT INTO gsm_skills (id, name, game_system, improvable, innate_skill, initialwert, basis_wert) VALUES (?, ?, ?, ?, ?, 5, 0)`,
|
||||||
|
skill.ID, skill.Name, skill.GameSystem, skill.Improvable, skill.InnateSkill).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify source data
|
||||||
|
var sourceSkill models.Skill
|
||||||
|
err = sourceDB.First(&sourceSkill, 1).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "Hören", sourceSkill.Name)
|
||||||
|
t.Logf("DEBUG: Source skill Hören - Improvable: %v, InnateSkill: %v", sourceSkill.Improvable, sourceSkill.InnateSkill)
|
||||||
|
|
||||||
|
// Also check raw data from database
|
||||||
|
var rawImprovable int
|
||||||
|
err = sourceDB.Raw("SELECT improvable FROM gsm_skills WHERE id = 1").Scan(&rawImprovable).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Logf("DEBUG: Raw SQL value for improvable: %d", rawImprovable)
|
||||||
|
|
||||||
|
assert.False(t, sourceSkill.Improvable, "Source skill should have Improvable=false")
|
||||||
|
|
||||||
|
// Copy data using copyTableData
|
||||||
|
err = copyTableData(sourceDB, targetDB, &models.Skill{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify all skills in target database
|
||||||
|
var targetSkills []models.Skill
|
||||||
|
err = targetDB.Find(&targetSkills).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, targetSkills, 3, "Should have 3 skills in target")
|
||||||
|
|
||||||
|
// Check each skill's Improvable field
|
||||||
|
expectedValues := map[uint]bool{
|
||||||
|
1: false, // Hören
|
||||||
|
2: true, // Alchimie
|
||||||
|
3: false, // Nachtsicht
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, targetSkill := range targetSkills {
|
||||||
|
expectedImprovable := expectedValues[targetSkill.ID]
|
||||||
|
assert.Equal(t, expectedImprovable, targetSkill.Improvable,
|
||||||
|
"Skill %s (ID: %d) should have Improvable=%v, got %v",
|
||||||
|
targetSkill.Name, targetSkill.ID, expectedImprovable, targetSkill.Improvable)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specific checks
|
||||||
|
var hoeren models.Skill
|
||||||
|
err = targetDB.Where("name = ?", "Hören").First(&hoeren).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.False(t, hoeren.Improvable, "Hören should have Improvable=false after transfer")
|
||||||
|
|
||||||
|
var alchimie models.Skill
|
||||||
|
err = targetDB.Where("name = ?", "Alchimie").First(&alchimie).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, alchimie.Improvable, "Alchimie should have Improvable=true after transfer")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestImprovableFieldInPreparedTestDB verifies the prepared test database has correct Improvable values
|
||||||
|
func TestImprovableFieldInPreparedTestDB(t *testing.T) {
|
||||||
|
setupTestEnvironment(t)
|
||||||
|
|
||||||
|
// Ensure clean database state before setup
|
||||||
|
database.ResetTestDB()
|
||||||
|
|
||||||
|
// Use the prepared test database
|
||||||
|
database.SetupTestDB(true)
|
||||||
|
require.NotNil(t, database.DB)
|
||||||
|
|
||||||
|
// Ensure database cleanup after test
|
||||||
|
t.Cleanup(func() {
|
||||||
|
database.ResetTestDB()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check specific skills that should have Improvable=false (innate skills)
|
||||||
|
innateSkills := []string{"Hören", "Nachtsicht", "Riechen", "Sechster Sinn", "Sehen"}
|
||||||
|
|
||||||
|
for _, skillName := range innateSkills {
|
||||||
|
var skill models.Skill
|
||||||
|
err := database.DB.Where("name = ?", skillName).First(&skill).Error
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
t.Logf("Skill %s not found in prepared test DB - skipping", skillName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// These are innate skills and should not be improvable
|
||||||
|
assert.True(t, skill.InnateSkill, "Skill %s should be marked as InnateSkill", skillName)
|
||||||
|
// Note: Based on game rules, innate skills are typically not improvable
|
||||||
|
t.Logf("Skill: %s, Improvable: %v, InnateSkill: %v", skillName, skill.Improvable, skill.InnateSkill)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check a regular skill that should be improvable
|
||||||
|
var alchimie models.Skill
|
||||||
|
err := database.DB.Where("name = ?", "Alchimie").First(&alchimie).Error
|
||||||
|
if err != gorm.ErrRecordNotFound {
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, alchimie.Improvable, "Alchimie should be improvable")
|
||||||
|
assert.False(t, alchimie.InnateSkill, "Alchimie should not be an innate skill")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// getModelTypeName returns the type name of a model
|
// getModelTypeName returns the type name of a model
|
||||||
func getModelTypeName(model interface{}) string {
|
func getModelTypeName(model interface{}) string {
|
||||||
switch model.(type) {
|
switch model.(type) {
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ func learningMigrateStructure(db ...*gorm.DB) error {
|
|||||||
&SkillCategoryDifficulty{},
|
&SkillCategoryDifficulty{},
|
||||||
&WeaponSkillCategoryDifficulty{},
|
&WeaponSkillCategoryDifficulty{},
|
||||||
&SkillImprovementCost{},
|
&SkillImprovementCost{},
|
||||||
&ClassLearningPoints{},
|
&ClassCategoryLearningPoints{},
|
||||||
&ClassSpellPoints{},
|
&ClassSpellPoints{},
|
||||||
&ClassTypicalSkill{},
|
&ClassTypicalSkill{},
|
||||||
&ClassTypicalSpell{},
|
&ClassTypicalSpell{},
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bamort/database"
|
||||||
"bamort/user"
|
"bamort/user"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
@@ -87,6 +88,70 @@ type CharacterCreationSpell struct {
|
|||||||
type CharacterCreationSkills []CharacterCreationSkill
|
type CharacterCreationSkills []CharacterCreationSkill
|
||||||
type CharacterCreationSpells []CharacterCreationSpell
|
type CharacterCreationSpells []CharacterCreationSpell
|
||||||
|
|
||||||
|
// ClassCategoryLearningPoints stores the learning points distribution for a character class
|
||||||
|
type ClassCategoryLearningPoints struct {
|
||||||
|
ID uint `gorm:"primaryKey" json:"id"`
|
||||||
|
CharacterClassID uint `gorm:"uniqueIndex:idx_class_category;not null" json:"character_class_id"`
|
||||||
|
SkillCategoryID uint `gorm:"uniqueIndex:idx_class_category;not null" json:"skill_category_id"`
|
||||||
|
Points int `gorm:"not null;default:0" json:"points"`
|
||||||
|
CharacterClass CharacterClass `gorm:"foreignKey:CharacterClassID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"character_class"`
|
||||||
|
SkillCategory SkillCategory `gorm:"foreignKey:SkillCategoryID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"skill_category"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassSpellPoints stores the spell learning points for a character class
|
||||||
|
type ClassSpellPoints struct {
|
||||||
|
ID uint `gorm:"primaryKey" json:"id"`
|
||||||
|
CharacterClassID uint `gorm:"uniqueIndex;not null" json:"character_class_id"`
|
||||||
|
SpellPoints int `gorm:"not null;default:0" json:"spell_points"` // Zauberlerneinheiten
|
||||||
|
CharacterClass CharacterClass `gorm:"foreignKey:CharacterClassID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"character_class"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassTypicalSkill stores typical skills for a character class with bonuses
|
||||||
|
type ClassTypicalSkill struct {
|
||||||
|
ID uint `gorm:"primaryKey" json:"id"`
|
||||||
|
CharacterClassID uint `gorm:"not null;index" json:"character_class_id"`
|
||||||
|
SkillID uint `gorm:"not null;index" json:"skill_id"`
|
||||||
|
Bonus int `gorm:"not null;default:0" json:"bonus"`
|
||||||
|
Attribute string `gorm:"size:10" json:"attribute,omitempty"` // z.B. "Gs", "In", "St"
|
||||||
|
Notes string `json:"notes,omitempty"` // Zusätzliche Notizen
|
||||||
|
CharacterClass CharacterClass `gorm:"foreignKey:CharacterClassID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"character_class"`
|
||||||
|
Skill Skill `gorm:"foreignKey:SkillID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"skill"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassTypicalSpell stores typical spells for a character class
|
||||||
|
type ClassTypicalSpell struct {
|
||||||
|
ID uint `gorm:"primaryKey" json:"id"`
|
||||||
|
CharacterClassID uint `gorm:"not null;index" json:"character_class_id"`
|
||||||
|
SpellID uint `gorm:"not null;index" json:"spell_id"`
|
||||||
|
Notes string `json:"notes,omitempty"` // z.B. "beliebig außer Dweomer"
|
||||||
|
CharacterClass CharacterClass `gorm:"foreignKey:CharacterClassID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"character_class"`
|
||||||
|
Spell Spell `gorm:"foreignKey:SpellID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"spell"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName specifies the table name for ClassLearningPoints
|
||||||
|
func (ClassCategoryLearningPoints) TableName() string {
|
||||||
|
//class_learning_points
|
||||||
|
return "gsm_cc_class_category_points"
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName specifies the table name for ClassSpellPoints
|
||||||
|
func (ClassSpellPoints) TableName() string {
|
||||||
|
//class_spell_points
|
||||||
|
return "gsm_cc_class_spell_points"
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName specifies the table name for ClassTypicalSkill
|
||||||
|
func (ClassTypicalSkill) TableName() string {
|
||||||
|
//class_typical_skills
|
||||||
|
return "gsm_cc_class_typical_skills"
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName specifies the table name for ClassTypicalSpell
|
||||||
|
func (ClassTypicalSpell) TableName() string {
|
||||||
|
//class_typical_spells
|
||||||
|
return "gsm_cc_class_typical_spells"
|
||||||
|
}
|
||||||
|
|
||||||
// JSON scanning methods for Skills slice
|
// JSON scanning methods for Skills slice
|
||||||
func (s *CharacterCreationSkills) Scan(value interface{}) error {
|
func (s *CharacterCreationSkills) Scan(value interface{}) error {
|
||||||
if value == nil {
|
if value == nil {
|
||||||
@@ -201,3 +266,37 @@ func GetUserSessions(db *gorm.DB, userID uint) ([]CharacterCreationSession, erro
|
|||||||
err := db.Where("user_id = ? AND expires_at > ?", userID, time.Now()).Find(&sessions).Error
|
err := db.Where("user_id = ? AND expires_at > ?", userID, time.Now()).Find(&sessions).Error
|
||||||
return sessions, err
|
return sessions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLearningPointsForClass retrieves all learning points for a character class
|
||||||
|
func GetLearningPointsForClass(classID uint) ([]ClassCategoryLearningPoints, error) {
|
||||||
|
var points []ClassCategoryLearningPoints
|
||||||
|
err := database.DB.Preload("SkillCategory").Where("character_class_id = ?", classID).Find(&points).Error
|
||||||
|
return points, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpellPointsForClass retrieves spell points for a character class
|
||||||
|
func GetSpellPointsForClass(classID uint) (*ClassSpellPoints, error) {
|
||||||
|
var points ClassSpellPoints
|
||||||
|
err := database.DB.Where("character_class_id = ?", classID).First(&points).Error
|
||||||
|
if err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return &ClassSpellPoints{SpellPoints: 0}, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &points, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTypicalSkillsForClass retrieves typical skills for a character class
|
||||||
|
func GetTypicalSkillsForClass(classID uint) ([]ClassTypicalSkill, error) {
|
||||||
|
var skills []ClassTypicalSkill
|
||||||
|
err := database.DB.Preload("Skill").Where("character_class_id = ?", classID).Find(&skills).Error
|
||||||
|
return skills, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTypicalSpellsForClass retrieves typical spells for a character class
|
||||||
|
func GetTypicalSpellsForClass(classID uint) ([]ClassTypicalSpell, error) {
|
||||||
|
var spells []ClassTypicalSpell
|
||||||
|
err := database.DB.Preload("Spell").Where("character_class_id = ?", classID).Find(&spells).Error
|
||||||
|
return spells, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bamort/database"
|
|
||||||
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ClassLearningPoints stores the learning points distribution for a character class
|
|
||||||
type ClassLearningPoints struct {
|
|
||||||
ID uint `gorm:"primaryKey" json:"id"`
|
|
||||||
CharacterClassID uint `gorm:"uniqueIndex:idx_class_category;not null" json:"character_class_id"`
|
|
||||||
SkillCategoryID uint `gorm:"uniqueIndex:idx_class_category;not null" json:"skill_category_id"`
|
|
||||||
Points int `gorm:"not null;default:0" json:"points"`
|
|
||||||
CharacterClass CharacterClass `gorm:"foreignKey:CharacterClassID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"character_class"`
|
|
||||||
SkillCategory SkillCategory `gorm:"foreignKey:SkillCategoryID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"skill_category"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClassSpellPoints stores the spell learning points for a character class
|
|
||||||
type ClassSpellPoints struct {
|
|
||||||
ID uint `gorm:"primaryKey" json:"id"`
|
|
||||||
CharacterClassID uint `gorm:"uniqueIndex;not null" json:"character_class_id"`
|
|
||||||
SpellPoints int `gorm:"not null;default:0" json:"spell_points"` // Zauberlerneinheiten
|
|
||||||
CharacterClass CharacterClass `gorm:"foreignKey:CharacterClassID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"character_class"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClassTypicalSkill stores typical skills for a character class with bonuses
|
|
||||||
type ClassTypicalSkill struct {
|
|
||||||
ID uint `gorm:"primaryKey" json:"id"`
|
|
||||||
CharacterClassID uint `gorm:"not null;index" json:"character_class_id"`
|
|
||||||
SkillID uint `gorm:"not null;index" json:"skill_id"`
|
|
||||||
Bonus int `gorm:"not null;default:0" json:"bonus"`
|
|
||||||
Attribute string `gorm:"size:10" json:"attribute,omitempty"` // z.B. "Gs", "In", "St"
|
|
||||||
Notes string `json:"notes,omitempty"` // Zusätzliche Notizen
|
|
||||||
CharacterClass CharacterClass `gorm:"foreignKey:CharacterClassID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"character_class"`
|
|
||||||
Skill Skill `gorm:"foreignKey:SkillID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"skill"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClassTypicalSpell stores typical spells for a character class
|
|
||||||
type ClassTypicalSpell struct {
|
|
||||||
ID uint `gorm:"primaryKey" json:"id"`
|
|
||||||
CharacterClassID uint `gorm:"not null;index" json:"character_class_id"`
|
|
||||||
SpellID uint `gorm:"not null;index" json:"spell_id"`
|
|
||||||
Notes string `json:"notes,omitempty"` // z.B. "beliebig außer Dweomer"
|
|
||||||
CharacterClass CharacterClass `gorm:"foreignKey:CharacterClassID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"character_class"`
|
|
||||||
Spell Spell `gorm:"foreignKey:SpellID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"spell"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName specifies the table name for ClassLearningPoints
|
|
||||||
func (ClassLearningPoints) TableName() string {
|
|
||||||
return "class_learning_points"
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName specifies the table name for ClassSpellPoints
|
|
||||||
func (ClassSpellPoints) TableName() string {
|
|
||||||
return "class_spell_points"
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName specifies the table name for ClassTypicalSkill
|
|
||||||
func (ClassTypicalSkill) TableName() string {
|
|
||||||
return "class_typical_skills"
|
|
||||||
}
|
|
||||||
|
|
||||||
// TableName specifies the table name for ClassTypicalSpell
|
|
||||||
func (ClassTypicalSpell) TableName() string {
|
|
||||||
return "class_typical_spells"
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLearningPointsForClass retrieves all learning points for a character class
|
|
||||||
func GetLearningPointsForClass(classID uint) ([]ClassLearningPoints, error) {
|
|
||||||
var points []ClassLearningPoints
|
|
||||||
err := database.DB.Preload("SkillCategory").Where("character_class_id = ?", classID).Find(&points).Error
|
|
||||||
return points, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSpellPointsForClass retrieves spell points for a character class
|
|
||||||
func GetSpellPointsForClass(classID uint) (*ClassSpellPoints, error) {
|
|
||||||
var points ClassSpellPoints
|
|
||||||
err := database.DB.Where("character_class_id = ?", classID).First(&points).Error
|
|
||||||
if err != nil {
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return &ClassSpellPoints{SpellPoints: 0}, nil
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &points, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTypicalSkillsForClass retrieves typical skills for a character class
|
|
||||||
func GetTypicalSkillsForClass(classID uint) ([]ClassTypicalSkill, error) {
|
|
||||||
var skills []ClassTypicalSkill
|
|
||||||
err := database.DB.Preload("Skill").Where("character_class_id = ?", classID).Find(&skills).Error
|
|
||||||
return skills, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTypicalSpellsForClass retrieves typical spells for a character class
|
|
||||||
func GetTypicalSpellsForClass(classID uint) ([]ClassTypicalSpell, error) {
|
|
||||||
var spells []ClassTypicalSpell
|
|
||||||
err := database.DB.Preload("Spell").Where("character_class_id = ?", classID).Find(&spells).Error
|
|
||||||
return spells, err
|
|
||||||
}
|
|
||||||
@@ -54,8 +54,8 @@ type Skill struct {
|
|||||||
Initialwert int `gorm:"default:5" json:"initialwert"`
|
Initialwert int `gorm:"default:5" json:"initialwert"`
|
||||||
BasisWert int `gorm:"default:0" json:"basiswert"`
|
BasisWert int `gorm:"default:0" json:"basiswert"`
|
||||||
Bonuseigenschaft string `json:"bonuseigenschaft,omitempty"`
|
Bonuseigenschaft string `json:"bonuseigenschaft,omitempty"`
|
||||||
Improvable bool `gorm:"default:true" json:"improvable"`
|
Improvable bool `json:"improvable"`
|
||||||
InnateSkill bool `gorm:"default:false" json:"innateskill"`
|
InnateSkill bool `json:"innateskill"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
Difficulty string `json:"difficulty"`
|
Difficulty string `json:"difficulty"`
|
||||||
}
|
}
|
||||||
@@ -136,6 +136,14 @@ func (object *Skill) TableName() string {
|
|||||||
func (stamm *Skill) Create() error {
|
func (stamm *Skill) Create() error {
|
||||||
gameSystem := "midgard"
|
gameSystem := "midgard"
|
||||||
stamm.GameSystem = gameSystem
|
stamm.GameSystem = gameSystem
|
||||||
|
|
||||||
|
// Set default values for boolean fields if not explicitly set
|
||||||
|
// Note: We cannot rely on GORM defaults anymore since they interfere with copying operations
|
||||||
|
if !stamm.Improvable && !stamm.InnateSkill {
|
||||||
|
// If both are false, set Improvable to true as default (most skills are improvable)
|
||||||
|
stamm.Improvable = true
|
||||||
|
}
|
||||||
|
|
||||||
err := database.DB.Transaction(func(tx *gorm.DB) error {
|
err := database.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
// Save the main character record
|
// Save the main character record
|
||||||
if err := tx.Create(&stamm).Error; err != nil {
|
if err := tx.Create(&stamm).Error; err != nil {
|
||||||
@@ -250,6 +258,12 @@ func (object *WeaponSkill) TableName() string {
|
|||||||
func (stamm *WeaponSkill) Create() error {
|
func (stamm *WeaponSkill) Create() error {
|
||||||
gameSystem := "midgard"
|
gameSystem := "midgard"
|
||||||
stamm.GameSystem = gameSystem
|
stamm.GameSystem = gameSystem
|
||||||
|
|
||||||
|
// Set default values for boolean fields if not explicitly set
|
||||||
|
if !stamm.Improvable && !stamm.InnateSkill {
|
||||||
|
stamm.Improvable = true
|
||||||
|
}
|
||||||
|
|
||||||
err := database.DB.Transaction(func(tx *gorm.DB) error {
|
err := database.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
// Save the main character record
|
// Save the main character record
|
||||||
if err := tx.Create(&stamm).Error; err != nil {
|
if err := tx.Create(&stamm).Error; err != nil {
|
||||||
@@ -649,8 +663,8 @@ func (object *Believe) Save() error {
|
|||||||
func GetBelievesByActiveSources(gameSystem string) ([]Believe, error) {
|
func GetBelievesByActiveSources(gameSystem string) ([]Believe, error) {
|
||||||
var believes []Believe
|
var believes []Believe
|
||||||
err := database.DB.
|
err := database.DB.
|
||||||
Joins("LEFT JOIN learning_sources ON gsm_believes.source_id = learning_sources.id").
|
Joins("LEFT JOIN gsm_lit_sources ON gsm_believes.source_id = gsm_lit_sources.id").
|
||||||
Where("gsm_believes.game_system = ? AND (learning_sources.is_active = ? OR gsm_believes.source_id IS NULL)", gameSystem, true).
|
Where("gsm_believes.game_system = ? AND (gsm_lit_sources.is_active = ? OR gsm_believes.source_id IS NULL)", gameSystem, true).
|
||||||
Order("gsm_believes.name ASC").
|
Order("gsm_believes.name ASC").
|
||||||
Find(&believes).Error
|
Find(&believes).Error
|
||||||
return believes, err
|
return believes, err
|
||||||
|
|||||||
@@ -1707,6 +1707,90 @@ func TestLearnCost_StructFields(t *testing.T) {
|
|||||||
assert.Equal(t, 2, learnCost.PP)
|
assert.Equal(t, 2, learnCost.PP)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSkill_Create_DefaultImprovable verifies that new skills get Improvable=true by default
|
||||||
|
func TestSkill_Create_DefaultImprovable(t *testing.T) {
|
||||||
|
database.SetupTestDB(true)
|
||||||
|
|
||||||
|
// Test 1: Create skill without setting Improvable or InnateSkill
|
||||||
|
skill1 := Skill{
|
||||||
|
Name: "Test Skill Default",
|
||||||
|
GameSystem: "midgard",
|
||||||
|
Category: "test",
|
||||||
|
Initialwert: 5,
|
||||||
|
}
|
||||||
|
err := skill1.Create()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify it was saved with Improvable=true (default for normal skills)
|
||||||
|
var savedSkill Skill
|
||||||
|
err = database.DB.Where("name = ?", "Test Skill Default").First(&savedSkill).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, savedSkill.Improvable, "Default skill should have Improvable=true")
|
||||||
|
assert.False(t, savedSkill.InnateSkill, "Default skill should have InnateSkill=false")
|
||||||
|
|
||||||
|
// Test 2: Create skill with explicit Improvable=false and InnateSkill=true
|
||||||
|
skill2 := Skill{
|
||||||
|
Name: "Test Innate Skill",
|
||||||
|
GameSystem: "midgard",
|
||||||
|
Category: "test",
|
||||||
|
Initialwert: 5,
|
||||||
|
Improvable: false,
|
||||||
|
InnateSkill: true,
|
||||||
|
}
|
||||||
|
err = skill2.Create()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify explicit values were preserved
|
||||||
|
var savedSkill2 Skill
|
||||||
|
err = database.DB.Where("name = ?", "Test Innate Skill").First(&savedSkill2).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.False(t, savedSkill2.Improvable, "Innate skill should have Improvable=false")
|
||||||
|
assert.True(t, savedSkill2.InnateSkill, "Innate skill should have InnateSkill=true")
|
||||||
|
|
||||||
|
// Test 3: Create skill with explicit Improvable=true
|
||||||
|
skill3 := Skill{
|
||||||
|
Name: "Test Explicit Improvable",
|
||||||
|
GameSystem: "midgard",
|
||||||
|
Category: "test",
|
||||||
|
Initialwert: 5,
|
||||||
|
Improvable: true,
|
||||||
|
InnateSkill: false,
|
||||||
|
}
|
||||||
|
err = skill3.Create()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify explicit values were preserved
|
||||||
|
var savedSkill3 Skill
|
||||||
|
err = database.DB.Where("name = ?", "Test Explicit Improvable").First(&savedSkill3).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, savedSkill3.Improvable, "Explicit improvable skill should have Improvable=true")
|
||||||
|
assert.False(t, savedSkill3.InnateSkill, "Explicit improvable skill should have InnateSkill=false")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWeaponSkill_Create_DefaultImprovable verifies that new weapon skills get Improvable=true by default
|
||||||
|
func TestWeaponSkill_Create_DefaultImprovable(t *testing.T) {
|
||||||
|
database.SetupTestDB(true)
|
||||||
|
|
||||||
|
// Test 1: Create weapon skill without setting Improvable or InnateSkill
|
||||||
|
weaponSkill := WeaponSkill{
|
||||||
|
Skill: Skill{
|
||||||
|
Name: "Test Weapon Skill",
|
||||||
|
GameSystem: "midgard",
|
||||||
|
Category: "weapon",
|
||||||
|
Initialwert: 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := weaponSkill.Create()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify it was saved with Improvable=true
|
||||||
|
var savedSkill WeaponSkill
|
||||||
|
err = database.DB.Where("name = ?", "Test Weapon Skill").First(&savedSkill).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, savedSkill.Improvable, "Default weapon skill should have Improvable=true")
|
||||||
|
assert.False(t, savedSkill.InnateSkill, "Default weapon skill should have InnateSkill=false")
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Additional Benchmark Tests
|
// Additional Benchmark Tests
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|||||||
@@ -182,11 +182,13 @@ type AuditLogEntry struct {
|
|||||||
|
|
||||||
// TableName-Methoden für GORM
|
// TableName-Methoden für GORM
|
||||||
func (Source) TableName() string {
|
func (Source) TableName() string {
|
||||||
return "learning_sources"
|
//learning_sources
|
||||||
|
return "gsm_lit_sources"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (CharacterClass) TableName() string {
|
func (CharacterClass) TableName() string {
|
||||||
return "learning_character_classes"
|
//learning_character_classes
|
||||||
|
return "gsm_character_classes"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (SkillCategory) TableName() string {
|
func (SkillCategory) TableName() string {
|
||||||
@@ -479,8 +481,8 @@ func GetSourcesByGameSystem(gameSystem string) ([]Source, error) {
|
|||||||
func GetSkillsByActiveSources(gameSystem string) ([]Skill, error) {
|
func GetSkillsByActiveSources(gameSystem string) ([]Skill, error) {
|
||||||
var skills []Skill
|
var skills []Skill
|
||||||
err := database.DB.
|
err := database.DB.
|
||||||
Joins("LEFT JOIN learning_sources ON gsm_skills.source_id = learning_sources.id").
|
Joins("LEFT JOIN gsm_lit_sources ON gsm_skills.source_id = gsm_lit_sources.id").
|
||||||
Where("gsm_skills.game_system = ? AND (learning_sources.is_active = ? OR gsm_skills.source_id IS NULL)", gameSystem, true).
|
Where("gsm_skills.game_system = ? AND (gsm_lit_sourcesis_active = ? OR gsm_skills.source_id IS NULL)", gameSystem, true).
|
||||||
Find(&skills).Error
|
Find(&skills).Error
|
||||||
return skills, err
|
return skills, err
|
||||||
}
|
}
|
||||||
@@ -489,8 +491,8 @@ func GetSkillsByActiveSources(gameSystem string) ([]Skill, error) {
|
|||||||
func GetSpellsByActiveSources(gameSystem string) ([]Spell, error) {
|
func GetSpellsByActiveSources(gameSystem string) ([]Spell, error) {
|
||||||
var spells []Spell
|
var spells []Spell
|
||||||
err := database.DB.
|
err := database.DB.
|
||||||
Joins("LEFT JOIN learning_sources ON gsm_spells.source_id = learning_sources.id").
|
Joins("LEFT JOIN gsm_lit_sources ON gsm_spells.source_id = gsm_lit_sources.id").
|
||||||
Where("gsm_spells.game_system = ? AND (learning_sources.is_active = ? OR gsm_spells.source_id IS NULL)", gameSystem, true).
|
Where("gsm_spells.game_system = ? AND (gsm_lit_sources.is_active = ? OR gsm_spells.source_id IS NULL)", gameSystem, true).
|
||||||
Find(&spells).Error
|
Find(&spells).Error
|
||||||
return spells, err
|
return spells, err
|
||||||
}
|
}
|
||||||
@@ -499,8 +501,8 @@ func GetSpellsByActiveSources(gameSystem string) ([]Spell, error) {
|
|||||||
func GetCharacterClassesByActiveSources(gameSystem string) ([]CharacterClass, error) {
|
func GetCharacterClassesByActiveSources(gameSystem string) ([]CharacterClass, error) {
|
||||||
var classes []CharacterClass
|
var classes []CharacterClass
|
||||||
err := database.DB.
|
err := database.DB.
|
||||||
Joins("LEFT JOIN learning_sources ON learning_character_classes.source_id = learning_sources.id").
|
Joins("LEFT JOIN gsm_lit_sources ON gsm_character_classes.source_id = gsm_lit_sources.id").
|
||||||
Where("learning_character_classes.game_system = ? AND (learning_sources.is_active = ? OR learning_character_classes.source_id IS NULL)", gameSystem, true).
|
Where("gsm_character_classes.game_system = ? AND (gsm_lit_sources.is_active = ? OR gsm_character_classes.source_id IS NULL)", gameSystem, true).
|
||||||
Find(&classes).Error
|
Find(&classes).Error
|
||||||
return classes, err
|
return classes, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,15 +34,15 @@ type SkZauber struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (object *SkFertigkeit) TableName() string {
|
func (object *SkFertigkeit) TableName() string {
|
||||||
dbPrefix := "skill"
|
dbPrefix := "char"
|
||||||
return dbPrefix + "_" + "skills"
|
return dbPrefix + "_" + "skills"
|
||||||
}
|
}
|
||||||
func (object *SkWaffenfertigkeit) TableName() string {
|
func (object *SkWaffenfertigkeit) TableName() string {
|
||||||
dbPrefix := "skill"
|
dbPrefix := "char"
|
||||||
return dbPrefix + "_" + "weaponskills"
|
return dbPrefix + "_" + "weaponskills"
|
||||||
}
|
}
|
||||||
func (object *SkZauber) TableName() string {
|
func (object *SkZauber) TableName() string {
|
||||||
dbPrefix := "skill"
|
dbPrefix := "char"
|
||||||
return dbPrefix + "_" + "spells"
|
return dbPrefix + "_" + "spells"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ func (object *SkWaffenfertigkeit) GetSkillByName() *Skill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (object *SkFertigkeit) GetCategory() string {
|
func (object *SkFertigkeit) GetCategory() string {
|
||||||
// Always fetch category from gsmaster, ignoring the category field in skill_skills
|
// Always fetch category from gsmaster, ignoring the category field in char_skills
|
||||||
var gsmsk Skill
|
var gsmsk Skill
|
||||||
gsmsk.First(object.Name)
|
gsmsk.First(object.Name)
|
||||||
if gsmsk.ID == 0 {
|
if gsmsk.ID == 0 {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func createTestSkill(name string) *Skill {
|
|||||||
|
|
||||||
func TestSkFertigkeit_TableName(t *testing.T) {
|
func TestSkFertigkeit_TableName(t *testing.T) {
|
||||||
skill := SkFertigkeit{}
|
skill := SkFertigkeit{}
|
||||||
expected := "skill_skills"
|
expected := "char_skills"
|
||||||
actual := skill.TableName()
|
actual := skill.TableName()
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
@@ -176,7 +176,7 @@ func TestSkFertigkeit_StructTags(t *testing.T) {
|
|||||||
|
|
||||||
func TestSkWaffenfertigkeit_TableName(t *testing.T) {
|
func TestSkWaffenfertigkeit_TableName(t *testing.T) {
|
||||||
weaponSkill := SkWaffenfertigkeit{}
|
weaponSkill := SkWaffenfertigkeit{}
|
||||||
expected := "skill_weaponskills"
|
expected := "char_weaponskills"
|
||||||
actual := weaponSkill.TableName()
|
actual := weaponSkill.TableName()
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ func TestSkAngeboreneFertigkeit_Inheritance(t *testing.T) {
|
|||||||
|
|
||||||
func TestSkZauber_TableName(t *testing.T) {
|
func TestSkZauber_TableName(t *testing.T) {
|
||||||
spell := SkZauber{}
|
spell := SkZauber{}
|
||||||
expected := "skill_spells"
|
expected := "char_spells"
|
||||||
actual := spell.TableName()
|
actual := spell.TableName()
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
@@ -417,14 +417,14 @@ func TestTableNames_Consistency(t *testing.T) {
|
|||||||
weaponSkill := SkWaffenfertigkeit{}
|
weaponSkill := SkWaffenfertigkeit{}
|
||||||
spell := SkZauber{}
|
spell := SkZauber{}
|
||||||
|
|
||||||
assert.Equal(t, "skill_skills", skill.TableName())
|
assert.Equal(t, "char_skills", skill.TableName())
|
||||||
assert.Equal(t, "skill_weaponskills", weaponSkill.TableName())
|
assert.Equal(t, "char_weaponskills", weaponSkill.TableName())
|
||||||
assert.Equal(t, "skill_spells", spell.TableName())
|
assert.Equal(t, "char_spells", spell.TableName())
|
||||||
|
|
||||||
// All table names should start with "skill_"
|
// All table names should start with "char_"
|
||||||
assert.Contains(t, skill.TableName(), "skill_")
|
assert.Contains(t, skill.TableName(), "char_")
|
||||||
assert.Contains(t, weaponSkill.TableName(), "skill_")
|
assert.Contains(t, weaponSkill.TableName(), "char_")
|
||||||
assert.Contains(t, spell.TableName(), "skill_")
|
assert.Contains(t, spell.TableName(), "char_")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSkFertigkeit_EdgeCases(t *testing.T) {
|
func TestSkFertigkeit_EdgeCases(t *testing.T) {
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ func PopulateClassLearningPointsData() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
learningPoints := ClassLearningPoints{
|
learningPoints := ClassCategoryLearningPoints{
|
||||||
CharacterClassID: charClass.ID,
|
CharacterClassID: charClass.ID,
|
||||||
SkillCategoryID: category.ID,
|
SkillCategoryID: category.ID,
|
||||||
Points: points,
|
Points: points,
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ type DatabaseExport struct {
|
|||||||
GsmContainers []models.Container `json:"gsm_containers"`
|
GsmContainers []models.Container `json:"gsm_containers"`
|
||||||
GsmTransportations []models.Transportation `json:"gsm_transportations"`
|
GsmTransportations []models.Transportation `json:"gsm_transportations"`
|
||||||
GsmBelieves []models.Believe `json:"gsm_believes"`
|
GsmBelieves []models.Believe `json:"gsm_believes"`
|
||||||
|
Sources []models.Source `json:"gsm_lit_sources"`
|
||||||
|
CharacterClasses []models.CharacterClass `json:"gsm_character_classes"`
|
||||||
|
|
||||||
// Learning data
|
// Learning data
|
||||||
Sources []models.Source `json:"learning_sources"`
|
|
||||||
CharacterClasses []models.CharacterClass `json:"learning_character_classes"`
|
|
||||||
SkillCategories []models.SkillCategory `json:"learning_skill_categories"`
|
SkillCategories []models.SkillCategory `json:"learning_skill_categories"`
|
||||||
SkillDifficulties []models.SkillDifficulty `json:"learning_skill_difficulties"`
|
SkillDifficulties []models.SkillDifficulty `json:"learning_skill_difficulties"`
|
||||||
SpellSchools []models.SpellSchool `json:"learning_spell_schools"`
|
SpellSchools []models.SpellSchool `json:"learning_spell_schools"`
|
||||||
|
|||||||
Reference in New Issue
Block a user