From f8c1be3b990943354d815fc81239053e437fb8ba Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 28 Jan 2026 22:05:11 +0100 Subject: [PATCH] added GameSystemID to Equipment, Weapon, Container and Transportation --- .../gsmaster/equipment_enhanced_handlers.go | 57 ++++- backend/gsmaster/handlers.go | 234 +++++++++++++++++- backend/gsmaster/weapon_enhanced_handlers.go | 25 +- backend/maintenance/handlers.go | 5 + backend/models/database.go | 25 ++ backend/models/model_gsmaster.go | 115 ++++++--- backend/models/model_gsmaster_test.go | 109 ++++++++ 7 files changed, 505 insertions(+), 65 deletions(-) diff --git a/backend/gsmaster/equipment_enhanced_handlers.go b/backend/gsmaster/equipment_enhanced_handlers.go index 66e5bc5..7f5939d 100644 --- a/backend/gsmaster/equipment_enhanced_handlers.go +++ b/backend/gsmaster/equipment_enhanced_handlers.go @@ -16,9 +16,14 @@ type EquipmentWithCategories struct { } // GetEquipmentWithCategories retrieves equipment with all its information -func GetEquipmentWithCategories(equipmentID uint) (*EquipmentWithCategories, error) { +func GetEquipmentWithCategories(equipmentID uint, gs *models.GameSystem) (*EquipmentWithCategories, error) { var equipment models.Equipment - if err := database.DB.First(&equipment, equipmentID).Error; err != nil { + query := database.DB + if gs != nil { + query = query.Where("game_system=? OR game_system_id=?", gs.Name, gs.ID) + } + + if err := query.First(&equipment, equipmentID).Error; err != nil { return nil, err } @@ -30,15 +35,20 @@ func GetEquipmentWithCategories(equipmentID uint) (*EquipmentWithCategories, err } // GetAllEquipmentWithCategories retrieves all equipment -func GetAllEquipmentWithCategories() ([]EquipmentWithCategories, error) { +func GetAllEquipmentWithCategories(gs *models.GameSystem) ([]EquipmentWithCategories, error) { var equipments []models.Equipment - if err := database.DB.Find(&equipments).Error; err != nil { + query := database.DB + if gs != nil { + query = query.Where("game_system=? OR game_system_id=?", gs.Name, gs.ID) + } + + if err := query.Find(&equipments).Error; err != nil { return nil, err } result := make([]EquipmentWithCategories, len(equipments)) for i, equipment := range equipments { - equipmentWithCats, err := GetEquipmentWithCategories(equipment.ID) + equipmentWithCats, err := GetEquipmentWithCategories(equipment.ID, gs) if err != nil { return nil, err } @@ -54,11 +64,18 @@ type EquipmentUpdateRequest struct { } // UpdateEquipmentWithCategories updates equipment -func UpdateEquipmentWithCategories(equipmentID uint, req EquipmentUpdateRequest) error { +func UpdateEquipmentWithCategories(equipmentID uint, req EquipmentUpdateRequest, gs *models.GameSystem) error { // Start transaction return database.DB.Transaction(func(tx *gorm.DB) error { // Update equipment info - if err := tx.Model(&models.Equipment{}).Where("id = ?", equipmentID).Updates(req.Equipment).Error; err != nil { + query := tx.Model(&models.Equipment{}).Where("id = ?", equipmentID) + if gs != nil { + req.Equipment.GameSystem = gs.Name + req.Equipment.GameSystemId = gs.ID + query = query.Where("game_system=? OR game_system_id=?", gs.Name, gs.ID) + } + + if err := query.Updates(req.Equipment).Error; err != nil { return err } @@ -70,7 +87,12 @@ func UpdateEquipmentWithCategories(equipmentID uint, req EquipmentUpdateRequest) // GetEnhancedMDEquipment returns equipment with enhanced information func GetEnhancedMDEquipment(c *gin.Context) { - equipments, err := GetAllEquipmentWithCategories() + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + equipments, err := GetAllEquipmentWithCategories(gs) if err != nil { respondWithError(c, http.StatusInternalServerError, "Failed to retrieve equipment: "+err.Error()) return @@ -88,6 +110,11 @@ func GetEnhancedMDEquipment(c *gin.Context) { // GetEnhancedMDEquipmentItem returns a single equipment with enhanced information func GetEnhancedMDEquipmentItem(c *gin.Context) { + gs, ok := resolveGameSystem(c) + if !ok { + return + } + idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { @@ -95,7 +122,7 @@ func GetEnhancedMDEquipmentItem(c *gin.Context) { return } - equipment, err := GetEquipmentWithCategories(uint(id)) + equipment, err := GetEquipmentWithCategories(uint(id), gs) if err != nil { respondWithError(c, http.StatusNotFound, "Equipment not found") return @@ -106,6 +133,11 @@ func GetEnhancedMDEquipmentItem(c *gin.Context) { // UpdateEnhancedMDEquipmentItem updates equipment func UpdateEnhancedMDEquipmentItem(c *gin.Context) { + gs, ok := resolveGameSystem(c) + if !ok { + return + } + idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { @@ -119,16 +151,19 @@ func UpdateEnhancedMDEquipmentItem(c *gin.Context) { return } + req.Equipment.GameSystem = gs.Name + req.Equipment.GameSystemId = gs.ID + // Ensure the ID matches req.Equipment.ID = uint(id) - if err := UpdateEquipmentWithCategories(uint(id), req); err != nil { + if err := UpdateEquipmentWithCategories(uint(id), req, gs); err != nil { respondWithError(c, http.StatusInternalServerError, "Failed to update equipment: "+err.Error()) return } // Return updated equipment - equipment, err := GetEquipmentWithCategories(uint(id)) + equipment, err := GetEquipmentWithCategories(uint(id), gs) if err != nil { respondWithError(c, http.StatusInternalServerError, "Failed to retrieve updated equipment") return diff --git a/backend/gsmaster/handlers.go b/backend/gsmaster/handlers.go index f398c39..a02a4cc 100644 --- a/backend/gsmaster/handlers.go +++ b/backend/gsmaster/handlers.go @@ -23,6 +23,28 @@ func parseID(c *gin.Context) (uint, error) { return uint(intID), nil } +func resolveGameSystem(c *gin.Context) (*models.GameSystem, bool) { + gsIDStr := c.Query("game_system_id") + var gsID uint + if gsIDStr != "" { + id, err := strconv.ParseUint(gsIDStr, 10, 32) + if err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid game_system_id") + return nil, false + } + gsID = uint(id) + } + + gsName := c.Query("game_system") + gs := models.GetGameSystem(gsID, gsName) + if gs == nil { + respondWithError(c, http.StatusBadRequest, "Invalid game system") + return nil, false + } + + return gs, true +} + type Creator interface { Create() error } @@ -308,42 +330,234 @@ func DeleteMDSpell(c *gin.Context) { } func GetMDEquipments(c *gin.Context) { - getMDItems[models.Equipment](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + var equipments []models.Equipment + if err := database.DB.Where("game_system=? OR game_system_id=?", gs.Name, gs.ID).Find(&equipments).Error; err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to retrieve items") + return + } + + c.JSON(http.StatusOK, equipments) } func GetMDEquipment(c *gin.Context) { - getMDItem[models.Equipment](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + id, err := parseID(c) + if err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid ID format") + return + } + + equipment := &models.Equipment{GameSystem: gs.Name, GameSystemId: gs.ID} + if err := equipment.FirstId(id); err != nil { + respondWithError(c, http.StatusNotFound, "Item not found") + return + } + + c.JSON(http.StatusOK, equipment) } func UpdateMDEquipment(c *gin.Context) { - updateMDItem[models.Equipment](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + id, err := parseID(c) + if err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid ID format") + return + } + + equipment := &models.Equipment{GameSystem: gs.Name, GameSystemId: gs.ID} + if err := equipment.FirstId(id); err != nil { + respondWithError(c, http.StatusNotFound, "Item not found") + return + } + + if err := c.ShouldBindJSON(equipment); err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid input data") + return + } + + equipment.ID = id + equipment.GameSystem = gs.Name + equipment.GameSystemId = gs.ID + + if err := equipment.Save(); err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to update item: "+err.Error()) + return + } + + c.JSON(http.StatusOK, equipment) } func AddEquipment(c *gin.Context) { - addMDItem[models.Equipment](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + equipment := &models.Equipment{GameSystem: gs.Name, GameSystemId: gs.ID} + if err := c.ShouldBindJSON(equipment); err != nil { + respondWithError(c, http.StatusBadRequest, err.Error()) + return + } + + if equipment.GameSystemId == 0 && equipment.GameSystem == "" { + equipment.GameSystem = gs.Name + equipment.GameSystemId = gs.ID + } + + if err := equipment.Create(); err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to create item: "+err.Error()) + return + } + + c.JSON(http.StatusCreated, equipment) } func DeleteMDEquipment(c *gin.Context) { - deleteMDItem[models.Equipment](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + id, err := parseID(c) + if err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid ID format") + return + } + + if err := database.DB.Where("(game_system=? OR game_system_id=?) AND id = ?", gs.Name, gs.ID, id).Delete(&models.Equipment{}).Error; err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to delete item") + return + } + + c.JSON(http.StatusNoContent, nil) } // Refactored handler functions func GetMDWeapons(c *gin.Context) { - getMDItems[models.Weapon](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + var weapons []models.Weapon + if err := database.DB.Where("game_system=? OR game_system_id=?", gs.Name, gs.ID).Find(&weapons).Error; err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to retrieve items") + return + } + + c.JSON(http.StatusOK, weapons) } func GetMDWeapon(c *gin.Context) { - getMDItem[models.Weapon](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + id, err := parseID(c) + if err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid ID format") + return + } + + weapon := &models.Weapon{Equipment: models.Equipment{GameSystem: gs.Name, GameSystemId: gs.ID}} + if err := weapon.FirstId(id); err != nil { + respondWithError(c, http.StatusNotFound, "Item not found") + return + } + + c.JSON(http.StatusOK, weapon) } func UpdateMDWeapon(c *gin.Context) { - updateMDItem[models.Weapon](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + id, err := parseID(c) + if err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid ID format") + return + } + + weapon := &models.Weapon{Equipment: models.Equipment{GameSystem: gs.Name, GameSystemId: gs.ID}} + if err := weapon.FirstId(id); err != nil { + respondWithError(c, http.StatusNotFound, "Item not found") + return + } + + if err := c.ShouldBindJSON(weapon); err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid input data") + return + } + + weapon.ID = id + weapon.GameSystem = gs.Name + weapon.GameSystemId = gs.ID + + if err := weapon.Save(); err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to update item: "+err.Error()) + return + } + + c.JSON(http.StatusOK, weapon) } func AddWeapon(c *gin.Context) { - addMDItem[models.Weapon](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + weapon := &models.Weapon{Equipment: models.Equipment{GameSystem: gs.Name, GameSystemId: gs.ID}} + if err := c.ShouldBindJSON(weapon); err != nil { + respondWithError(c, http.StatusBadRequest, err.Error()) + return + } + + if weapon.GameSystemId == 0 && weapon.GameSystem == "" { + weapon.GameSystem = gs.Name + weapon.GameSystemId = gs.ID + } + + if err := weapon.Create(); err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to create item: "+err.Error()) + return + } + + c.JSON(http.StatusCreated, weapon) } func DeleteMDWeapon(c *gin.Context) { - deleteMDItem[models.Weapon](c) + gs, ok := resolveGameSystem(c) + if !ok { + return + } + + id, err := parseID(c) + if err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid ID format") + return + } + + if err := database.DB.Where("(game_system=? OR game_system_id=?) AND id = ?", gs.Name, gs.ID, id).Delete(&models.Weapon{}).Error; err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to delete item") + return + } + + c.JSON(http.StatusNoContent, nil) } diff --git a/backend/gsmaster/weapon_enhanced_handlers.go b/backend/gsmaster/weapon_enhanced_handlers.go index ef35945..1fdb0f7 100644 --- a/backend/gsmaster/weapon_enhanced_handlers.go +++ b/backend/gsmaster/weapon_enhanced_handlers.go @@ -11,6 +11,11 @@ import ( // GetEnhancedMDWeapons returns weapons with their source information func GetEnhancedMDWeapons(c *gin.Context) { + gs, ok := resolveGameSystem(c) + if !ok { + return + } + type EnhancedWeapon struct { models.Weapon SourceCode string `json:"source_code,omitempty"` @@ -22,7 +27,7 @@ func GetEnhancedMDWeapons(c *gin.Context) { } var weapons []models.Weapon - if err := database.DB.Find(&weapons).Error; err != nil { + if err := database.DB.Where("game_system=? OR game_system_id=?", gs.Name, gs.ID).Find(&weapons).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve weapons"}) return } @@ -56,6 +61,11 @@ func GetEnhancedMDWeapons(c *gin.Context) { // GetEnhancedMDWeapon returns a single weapon with source information func GetEnhancedMDWeapon(c *gin.Context) { + gs, ok := resolveGameSystem(c) + if !ok { + return + } + type EnhancedWeapon struct { models.Weapon SourceCode string `json:"source_code,omitempty"` @@ -68,7 +78,7 @@ func GetEnhancedMDWeapon(c *gin.Context) { } var weapon models.Weapon - if err := database.DB.First(&weapon, uint(id)).Error; err != nil { + if err := database.DB.Where("game_system=? OR game_system_id=?", gs.Name, gs.ID).First(&weapon, uint(id)).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Weapon not found"}) return } @@ -91,6 +101,11 @@ func GetEnhancedMDWeapon(c *gin.Context) { // UpdateEnhancedMDWeapon updates a weapon func UpdateEnhancedMDWeapon(c *gin.Context) { + gs, ok := resolveGameSystem(c) + if !ok { + return + } + id, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"}) @@ -98,7 +113,7 @@ func UpdateEnhancedMDWeapon(c *gin.Context) { } var weapon models.Weapon - if err := database.DB.First(&weapon, uint(id)).Error; err != nil { + if err := database.DB.Where("game_system=? OR game_system_id=?", gs.Name, gs.ID).First(&weapon, uint(id)).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Weapon not found"}) return } @@ -111,9 +126,11 @@ func UpdateEnhancedMDWeapon(c *gin.Context) { // Ensure ID stays the same weapon.ID = uint(id) + weapon.GameSystem = gs.Name + weapon.GameSystemId = gs.ID // Update the weapon - if err := database.DB.Save(&weapon).Error; err != nil { + if err := weapon.Save(); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update weapon"}) return } diff --git a/backend/maintenance/handlers.go b/backend/maintenance/handlers.go index 32a314b..9d814c3 100644 --- a/backend/maintenance/handlers.go +++ b/backend/maintenance/handlers.go @@ -81,6 +81,11 @@ func migrateDataIfNeeded(db *gorm.DB) error { logger.Error("Fehler beim Migrieren der GameSystem-Daten: %s", err.Error()) return fmt.Errorf("failed to migrate game system data: %w", err) } + err = models.MigrateDataIfNeeded(db) + if err != nil { + logger.Error("Fehler beim Migrieren der Models-Daten: %s", err.Error()) + return fmt.Errorf("failed to migrate models data: %w", err) + } // Kopiere categorie nach learning_category für Spells, wenn learning_category leer ist logger.Debug("Migriere Spell Learning Categories...") diff --git a/backend/models/database.go b/backend/models/database.go index d11a048..b1722e8 100644 --- a/backend/models/database.go +++ b/backend/models/database.go @@ -2,6 +2,9 @@ package models import ( "bamort/database" + "bamort/logger" + "fmt" + "strings" "gorm.io/gorm" ) @@ -189,3 +192,25 @@ func learningMigrateStructure(db ...*gorm.DB) error { } return nil } + +func MigrateDataIfNeeded(db ...*gorm.DB) error { + // Use provided DB or default to database.DB + var targetDB *gorm.DB + if len(db) > 0 && db[0] != nil { + targetDB = db[0] + } else { + targetDB = database.DB + } + sql := ` + UPDATE gsm_believes + SET game_system_id = 1 + WHERE game_system_id IS NULL or game_system_id = 0; + ` + logger.Debug("Führe SQL-Update aus: %s", strings.ReplaceAll(sql, "\n", " ")) + result := targetDB.Exec(sql) + if result.Error != nil { + logger.Error("Fehler beim SQL-Update der Spell Learning Categories: %s", result.Error.Error()) + return fmt.Errorf("failed to update spell learning categories: %w", result.Error) + } + return nil +} diff --git a/backend/models/model_gsmaster.go b/backend/models/model_gsmaster.go index 9fc83a5..6679632 100644 --- a/backend/models/model_gsmaster.go +++ b/backend/models/model_gsmaster.go @@ -91,6 +91,7 @@ type Spell struct { type Equipment struct { ID uint `gorm:"primaryKey" json:"id"` GameSystem string `gorm:"column:game_system;index;default:midgard" json:"game_system"` + GameSystemId uint `json:"game_system_id,omitempty"` Name string `gorm:"type:varchar(255);index" json:"name"` Beschreibung string `json:"beschreibung"` Quelle string `json:"quelle"` // Deprecated: Für Rückwärtskompatibilität @@ -421,26 +422,14 @@ func (object *Spell) GetSpellCategories() ([]string, error) { func (object *Spell) ensureGameSystem() { gs := GetGameSystem(object.GameSystemId, object.GameSystem) - - if object.GameSystemId == 0 { - object.GameSystemId = gs.ID - } - - if object.GameSystem == "" { - object.GameSystem = gs.Name - } + object.GameSystemId = gs.ID + object.GameSystem = gs.Name } func (object *Skill) ensureGameSystem() { gs := GetGameSystem(object.GameSystemId, object.GameSystem) - - if object.GameSystemId == 0 { - object.GameSystemId = gs.ID - } - - if object.GameSystem == "" { - object.GameSystem = gs.Name - } + object.GameSystemId = gs.ID + object.GameSystem = gs.Name } func (object *Skill) BeforeCreate(tx *gorm.DB) error { @@ -463,14 +452,29 @@ func (object *Spell) BeforeSave(tx *gorm.DB) error { return nil } +func (object *Equipment) ensureGameSystem() { + gs := GetGameSystem(object.GameSystemId, object.GameSystem) + object.GameSystemId = gs.ID + object.GameSystem = gs.Name +} + +func (object *Equipment) BeforeCreate(tx *gorm.DB) error { + object.ensureGameSystem() + return nil +} + +func (object *Equipment) BeforeSave(tx *gorm.DB) error { + object.ensureGameSystem() + return nil +} + func (object *Equipment) TableName() string { dbPrefix := "gsm" return dbPrefix + "_" + "equipments" } func (stamm *Equipment) Create() error { - gameSystem := "midgard" - stamm.GameSystem = gameSystem + stamm.ensureGameSystem() err := database.DB.Transaction(func(tx *gorm.DB) error { // Save the main character record if err := tx.Create(&stamm).Error; err != nil { @@ -486,8 +490,8 @@ func (stamm *Equipment) First(name string) error { if name == "" { return fmt.Errorf("name cannot be empty") } - gameSystem := "midgard" - err := database.DB.First(&stamm, "game_system=? AND name = ?", gameSystem, name).Error + gs := GetGameSystem(stamm.GameSystemId, stamm.GameSystem) + err := database.DB.First(&stamm, "(game_system=? OR game_system_id=?) AND name = ?", gs.Name, gs.ID, name).Error if err != nil { // zauber found return err @@ -496,8 +500,8 @@ func (stamm *Equipment) First(name string) error { } func (object *Equipment) FirstId(value uint) error { - gameSystem := "midgard" - err := database.DB.First(&object, "game_system=? AND id = ?", gameSystem, value).Error + gs := GetGameSystem(object.GameSystemId, object.GameSystem) + err := database.DB.First(&object, "(game_system=? OR game_system_id=?) AND id = ?", gs.Name, gs.ID, value).Error if err != nil { // zauber found return err @@ -506,6 +510,7 @@ func (object *Equipment) FirstId(value uint) error { } func (object *Equipment) Save() error { + object.ensureGameSystem() err := database.DB.Save(&object).Error if err != nil { // zauber found @@ -525,8 +530,7 @@ func (w *Weapon) IsRanged() bool { } func (stamm *Weapon) Create() error { - gameSystem := "midgard" - stamm.GameSystem = gameSystem + stamm.ensureGameSystem() err := database.DB.Transaction(func(tx *gorm.DB) error { // Save the main character record if err := tx.Create(&stamm).Error; err != nil { @@ -542,8 +546,8 @@ func (stamm *Weapon) First(name string) error { if name == "" { return fmt.Errorf("name cannot be empty") } - gameSystem := "midgard" - err := database.DB.First(&stamm, "game_system=? AND name = ?", gameSystem, name).Error + gs := GetGameSystem(stamm.GameSystemId, stamm.GameSystem) + err := database.DB.First(&stamm, "(game_system=? OR game_system_id=?) AND name = ?", gs.Name, gs.ID, name).Error if err != nil { // zauber found return err @@ -552,8 +556,8 @@ func (stamm *Weapon) First(name string) error { } func (object *Weapon) FirstId(id uint) error { - gameSystem := "midgard" - err := database.DB.First(&object, "game_system=? AND id = ?", gameSystem, id).Error + gs := GetGameSystem(object.GameSystemId, object.GameSystem) + err := database.DB.First(&object, "(game_system=? OR game_system_id=?) AND id = ?", gs.Name, gs.ID, id).Error if err != nil { return err } @@ -561,6 +565,7 @@ func (object *Weapon) FirstId(id uint) error { } func (object *Weapon) Save() error { + object.ensureGameSystem() err := database.DB.Save(&object).Error if err != nil { // zauber found @@ -569,14 +574,23 @@ func (object *Weapon) Save() error { return nil } +func (object *Weapon) BeforeCreate(tx *gorm.DB) error { + object.ensureGameSystem() + return nil +} + +func (object *Weapon) BeforeSave(tx *gorm.DB) error { + object.ensureGameSystem() + return nil +} + func (object *Container) TableName() string { dbPrefix := "gsm" return dbPrefix + "_" + "containers" } func (stamm *Container) Create() error { - gameSystem := "midgard" - stamm.GameSystem = gameSystem + stamm.ensureGameSystem() err := database.DB.Transaction(func(tx *gorm.DB) error { // Save the main character record if err := tx.Create(&stamm).Error; err != nil { @@ -592,8 +606,8 @@ func (stamm *Container) First(name string) error { if name == "" { return fmt.Errorf("name cannot be empty") } - gameSystem := "midgard" - err := database.DB.First(&stamm, "game_system=? AND name = ?", gameSystem, name).Error + gs := GetGameSystem(stamm.GameSystemId, stamm.GameSystem) + err := database.DB.First(&stamm, "(game_system=? OR game_system_id=?) AND name = ?", gs.Name, gs.ID, name).Error if err != nil { // zauber found return err @@ -602,8 +616,8 @@ func (stamm *Container) First(name string) error { } func (object *Container) FirstId(value uint) error { - gameSystem := "midgard" - err := database.DB.First(&object, "game_system=? AND id = ?", gameSystem, value).Error + gs := GetGameSystem(object.GameSystemId, object.GameSystem) + err := database.DB.First(&object, "(game_system=? OR game_system_id=?) AND id = ?", gs.Name, gs.ID, value).Error if err != nil { // zauber found return err @@ -612,6 +626,7 @@ func (object *Container) FirstId(value uint) error { } func (object *Container) Save() error { + object.ensureGameSystem() err := database.DB.Save(&object).Error if err != nil { // zauber found @@ -620,14 +635,23 @@ func (object *Container) Save() error { return nil } +func (object *Container) BeforeCreate(tx *gorm.DB) error { + object.ensureGameSystem() + return nil +} + +func (object *Container) BeforeSave(tx *gorm.DB) error { + object.ensureGameSystem() + return nil +} + func (object *Transportation) TableName() string { dbPrefix := "gsm" return dbPrefix + "_" + "transportations" } func (stamm *Transportation) Create() error { - gameSystem := "midgard" - stamm.GameSystem = gameSystem + stamm.ensureGameSystem() err := database.DB.Transaction(func(tx *gorm.DB) error { // Save the main character record if err := tx.Create(&stamm).Error; err != nil { @@ -640,8 +664,8 @@ func (stamm *Transportation) Create() error { } func (object *Transportation) FirstId(value uint) error { - gameSystem := "midgard" - err := database.DB.First(&object, "game_system=? AND id = ?", gameSystem, value).Error + gs := GetGameSystem(object.GameSystemId, object.GameSystem) + err := database.DB.First(&object, "(game_system=? OR game_system_id=?) AND id = ?", gs.Name, gs.ID, value).Error if err != nil { // zauber found return err @@ -653,8 +677,8 @@ func (stamm *Transportation) First(name string) error { if name == "" { return fmt.Errorf("name cannot be empty") } - gameSystem := "midgard" - err := database.DB.First(&stamm, "game_system=? AND name = ?", gameSystem, name).Error + gs := GetGameSystem(stamm.GameSystemId, stamm.GameSystem) + err := database.DB.First(&stamm, "(game_system=? OR game_system_id=?) AND name = ?", gs.Name, gs.ID, name).Error if err != nil { // zauber found return err @@ -663,6 +687,7 @@ func (stamm *Transportation) First(name string) error { } func (object *Transportation) Save() error { + object.ensureGameSystem() err := database.DB.Save(&object).Error if err != nil { // zauber found @@ -671,6 +696,16 @@ func (object *Transportation) Save() error { return nil } +func (object *Transportation) BeforeCreate(tx *gorm.DB) error { + object.ensureGameSystem() + return nil +} + +func (object *Transportation) BeforeSave(tx *gorm.DB) error { + object.ensureGameSystem() + return nil +} + func (object *Believe) TableName() string { dbPrefix := "gsm" return dbPrefix + "_" + "believes" diff --git a/backend/models/model_gsmaster_test.go b/backend/models/model_gsmaster_test.go index d152a7e..51eeb1e 100644 --- a/backend/models/model_gsmaster_test.go +++ b/backend/models/model_gsmaster_test.go @@ -682,6 +682,50 @@ func TestEquipment_Save(t *testing.T) { assert.Equal(t, "Updated equipment description", foundEquipment.Beschreibung) } +func TestEquipment_Create_SetsDefaultGameSystem(t *testing.T) { + setupGSMasterTestDB(t) + + equipment := &Equipment{ + Name: "TestDefaultEquipment", + Beschreibung: "Defaults to midgard", + Gewicht: 1.0, + Wert: 2.0, + PersonalItem: false, + } + + err := equipment.Create() + require.NoError(t, err) + assert.Equal(t, "midgard", equipment.GameSystem) + assert.NotZero(t, equipment.GameSystemId) +} + +func TestEquipment_First_UsesGameSystemId(t *testing.T) { + setupGSMasterTestDB(t) + + otherGS := &GameSystem{Code: "TST-EQ", Name: "TestSystemEquipment"} + require.NoError(t, database.DB.Create(otherGS).Error) + + defaultEquipment := createTestEquipment("SharedEquipmentName") + require.NoError(t, defaultEquipment.Create()) + + altEquipment := &Equipment{ + GameSystem: otherGS.Name, + GameSystemId: otherGS.ID, + Name: "SharedEquipmentName", + Beschreibung: "Alternate system", + Gewicht: 1.5, + Wert: 5.0, + PersonalItem: false, + } + require.NoError(t, altEquipment.Create()) + + found := &Equipment{GameSystemId: otherGS.ID} + err := found.First("SharedEquipmentName") + require.NoError(t, err) + assert.Equal(t, otherGS.ID, found.GameSystemId) + assert.Equal(t, otherGS.Name, found.GameSystem) +} + // ============================================================================= // Tests for Weapon struct // ============================================================================= @@ -704,6 +748,27 @@ func TestWeapon_Create(t *testing.T) { assert.Equal(t, "midgard", weapon.GameSystem) } +func TestWeapon_Create_SetsDefaultGameSystem(t *testing.T) { + setupGSMasterTestDB(t) + + weapon := &Weapon{ + Equipment: Equipment{ + Name: "TestWeaponDefaultGS", + Beschreibung: "Defaults to midgard", + Gewicht: 2.5, + Wert: 15.0, + PersonalItem: false, + }, + SkillRequired: "Einhandschwerter", + Damage: "1W6", + } + + err := weapon.Create() + require.NoError(t, err) + assert.Equal(t, "midgard", weapon.GameSystem) + assert.NotZero(t, weapon.GameSystemId) +} + func TestWeapon_First_Success(t *testing.T) { setupGSMasterTestDB(t) @@ -921,6 +986,27 @@ func TestContainer_Save(t *testing.T) { assert.Equal(t, 25.0, foundContainer.Tragkraft) } +func TestContainer_Create_SetsDefaultGameSystem(t *testing.T) { + setupGSMasterTestDB(t) + + container := &Container{ + Equipment: Equipment{ + Name: "TestContainerDefaultGS", + Beschreibung: "Defaults to midgard", + Gewicht: 0.3, + Wert: 3.0, + PersonalItem: false, + }, + Tragkraft: 5.0, + Volumen: 8.0, + } + + err := container.Create() + require.NoError(t, err) + assert.Equal(t, "midgard", container.GameSystem) + assert.NotZero(t, container.GameSystemId) +} + // ============================================================================= // Tests for Transportation struct // ============================================================================= @@ -1049,6 +1135,29 @@ func TestTransportation_Save(t *testing.T) { assert.Equal(t, 300.0, foundTransportation.Tragkraft) } +func TestTransportation_Create_SetsDefaultGameSystem(t *testing.T) { + setupGSMasterTestDB(t) + + transportation := &Transportation{ + Container: Container{ + Equipment: Equipment{ + Name: "TestTransportDefaultGS", + Beschreibung: "Defaults to midgard", + Gewicht: 20.0, + Wert: 200.0, + PersonalItem: false, + }, + Tragkraft: 100.0, + Volumen: 250.0, + }, + } + + err := transportation.Create() + require.NoError(t, err) + assert.Equal(t, "midgard", transportation.GameSystem) + assert.NotZero(t, transportation.GameSystemId) +} + // ============================================================================= // Tests for Believe struct // =============================================================================