diff --git a/src/gin-cpularp.go b/src/gin-cpularp.go index 26cef91..35a4cea 100755 --- a/src/gin-cpularp.go +++ b/src/gin-cpularp.go @@ -13,6 +13,7 @@ func main() { api.GlobalDatabase = database.InitializeDatabase() api.GlobalConfig.ParseConfig("../config.toml") api.GlobalOAuth = authdiscord.CreateDiscordOAuthConfig(api.GlobalConfig) + api.SetFilteredModels() router := gin.Default() router.Use(cors.New(cors.Config{ AllowOrigins: []string{api.GlobalConfig.GetFrontendRootDomain()}, diff --git a/src/lib/api/api.go b/src/lib/api/api.go index a04ef74..d8b869d 100644 --- a/src/lib/api/api.go +++ b/src/lib/api/api.go @@ -4,9 +4,12 @@ import ( "crypto/x509" "encoding/json" "encoding/pem" + "errors" + "io" "log" "net/http" "slices" + "strconv" "strings" authdiscord "example.com/auth/discord" @@ -36,6 +39,7 @@ import ( var GlobalDatabase *gorm.DB var GlobalConfig configserver.AppConfig var GlobalOAuth *oauth2.Config +var filteredModelNames []string // Private Functions @@ -122,6 +126,86 @@ func checkAuthentication(context *gin.Context) *oauth2.Token { return nil } +func validateBasicParams(context *gin.Context) (*[]uint, *[]byte) { + IDArray, IDOk := context.GetQueryArray("id") + body := []byte{} + var err error + if slices.Contains([]string{"POST", "PUT"}, context.Request.Method) { + if context.Request.Method == "PUT" && IDOk && len(IDArray) != 1 { + err = errors.New("invalid number of IDs were included") + log.Println(err) + context.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return nil, nil + } + body, err = io.ReadAll(context.Request.Body) + if err != nil { + log.Println(err) + context.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return nil, nil + } + if !json.Valid(body) { + err := errors.New("invalid JSON Body") + log.Println(err) + context.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return nil, nil + } + } + var IDUintArray []uint + for _, ID := range IDArray { + IDUint, err := strconv.Atoi(ID) + if err != nil { + log.Println(err) + context.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return nil, nil + } + IDUintArray = append(IDUintArray, uint(IDUint)) + } + return &IDUintArray, &body +} + +func validateRequest(context *gin.Context) (string, *[]uint, *[]byte) { + // Check that the method is valid + if !slices.Contains([]string{"GET", "POST", "PUT", "DELETE"}, context.Request.Method) { + err := errors.New("request must be GET, POST, PUT, or DELETE") + log.Println(err) + context.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return "", nil, nil + } + // Check authentication if not a GET request + if (context.Request.Method != "GET") && (checkAuthentication(context) == nil) { + err := errors.New("must be authenticated to make this kind of request") + log.Println(err) + context.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{ + "error": err.Error(), + }) + return "", nil, nil + } + // Get the object type from the request parameters + objectType := context.Param("object") + // Check that the object type is valid + if !slices.Contains(filteredModelNames, objectType) { + err := errors.New("requested object type does not exist") + log.Println(err) + context.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return "", nil, nil + } + // Validate and parse out required parameters from request + IDUintArray, body := validateBasicParams(context) + return objectType, IDUintArray, body +} + // Authentication Workflow func AuthCallback(context *gin.Context) { @@ -178,22 +262,13 @@ func AuthLogoutRedirect(context *gin.Context) { // Public Functions -func ObjectRequest(context *gin.Context) { - if !slices.Contains([]string{"GET", "POST", "PUT", "DELETE"}, context.Request.Method) { - context.AbortWithStatus(http.StatusBadRequest) - return - } - if (context.Request.Method != "GET") && (checkAuthentication(context) == nil) { - context.AbortWithStatus(http.StatusUnauthorized) - return - } +func SetFilteredModels() { var modelNames []string + filteredModelNames = []string{} result := GlobalDatabase.Table("sqlite_master").Where("type = ?", "table").Pluck("name", &modelNames) if result.Error != nil { - context.AbortWithStatus(http.StatusInternalServerError) - return + log.Fatal(errors.New("unable to access model names")) } - var filteredModelNames []string for _, model := range modelNames { if slices.Contains([]string{"api_keys", "sqlite_sequence"}, model) || slices.Contains(strings.Split(model, "_"), "associations") { continue @@ -202,52 +277,115 @@ func ObjectRequest(context *gin.Context) { model = strings.Replace(model, "_", "-", -1) filteredModelNames = append(filteredModelNames, model[:len(model)-1]) } - objectType := context.Param("object") - if !slices.Contains(filteredModelNames, objectType) { - context.AbortWithStatus(http.StatusBadRequest) +} + +func ObjectRequest(context *gin.Context) { + // Make sure request has valid parameters + objectType, IDUintArray, body := validateRequest(context) + // This shouldn't happen, but just in case... + if objectType == "" { return } + // Determine how to handle the request var err error + method := context.Request.Method + resultJSON := gin.H{} switch objectType { case "user": user.GetAll(GlobalDatabase) case "person": - person.GetAll(GlobalDatabase) + result, resultError := person.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "group": - err = group.HandleRequest(GlobalDatabase, context) + result, resultError := group.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "character": - character.GetAll(GlobalDatabase) + result, resultError := character.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "role": - role.GetAll(GlobalDatabase) + result, resultError := role.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "tier": - tier.GetAll(GlobalDatabase) + result, resultError := tier.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "function-set": - functionset.GetAll(GlobalDatabase) + result, resultError := functionset.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "function": - // result = function.Create(GlobalDatabase, context) - function.GetAll(GlobalDatabase) + result, resultError := function.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "function-tag": - // result = functiontag.Create(GlobalDatabase, context) - functiontag.GetAll(GlobalDatabase) + result, resultError := functiontag.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "inventory-slot": - inventoryslot.GetAll(GlobalDatabase) + result, resultError := inventoryslot.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "item": - item.GetAll(GlobalDatabase) + result, resultError := item.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "item-tag": - itemtag.GetAll(GlobalDatabase) + result, resultError := itemtag.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "customization": - customization.GetAll(GlobalDatabase) + result, resultError := customization.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } case "schematic": - schematic.GetAll(GlobalDatabase) + result, resultError := schematic.HandleRequest(method, GlobalDatabase, IDUintArray, body) + err = resultError + resultJSON = gin.H{ + "result": result, + } default: - context.AbortWithStatus(http.StatusBadRequest) + err = errors.New("request made for object that exists, but is not implemented") + context.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) return } if err != nil { - context.Status(http.StatusInternalServerError) + log.Println(err) + context.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) return } - context.Status(http.StatusOK) + context.JSON(http.StatusOK, resultJSON) } func CreateAPIToken(context *gin.Context) { diff --git a/src/lib/database/character/character.go b/src/lib/database/character/character.go index 50d8a2b..55d0a0e 100644 --- a/src/lib/database/character/character.go +++ b/src/lib/database/character/character.go @@ -1,7 +1,8 @@ package character import ( - "log" + "encoding/json" + "errors" functionset "example.com/database/functionset" inventoryslot "example.com/database/inventoryslot" @@ -13,14 +14,46 @@ import ( type Character struct { gorm.Model - Name string `gorm:"primaryKey; uniqueIndex" json:"name"` + Name string `gorm:"uniqueIndex" json:"name"` Owners []person.Person `gorm:"many2many:character_owner_associations" json:"owners"` // Unique Roles []role.Role `gorm:"many2many:character_role_associations" json:"roles"` // Unique FunctionSets []functionset.FunctionSet `gorm:"many2many:character_functionset_associations" json:"function_sets"` Inventory []inventoryslot.InventorySlot `gorm:"many2many:character_inventory_associations" json:"inventory"` } -func (character Character) Create(db *gorm.DB) error { +type CharacterParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + Name string `json:"name"` + Owners []uint `json:"owners"` + Roles []uint `json:"roles"` + FunctionSets []uint `json:"function_sets"` + Inventory []uint `json:"inventory_slot"` +} + +func (params *CharacterParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams CharacterParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + if inputParams.Name == "" { + return errors.New("input name cannot be empty") + } + params.Name = inputParams.Name + params.Owners = inputParams.Owners + params.Roles = inputParams.Roles + params.FunctionSets = inputParams.FunctionSets + params.Inventory = inputParams.Inventory + return nil +} + +func (character Character) create(db *gorm.DB) error { result := db.Create(&character) if result.Error != nil { return result.Error @@ -28,21 +61,28 @@ func (character Character) Create(db *gorm.DB) error { return nil } -func (character Character) getAssociations(db *gorm.DB) { +func (character *Character) getAssociations(db *gorm.DB) { db.Model(&character).Association("Owners").Find(&character.Owners) db.Model(&character).Association("Roles").Find(&character.Roles) db.Model(&character).Association("FunctionSets").Find(&character.FunctionSets) db.Model(&character).Association("Inventory").Find(&character.Inventory) } -func (character *Character) Get(db *gorm.DB, inputCharacter string) { - db.Where("name = ?", inputCharacter).Take(&character) +func (character *Character) get(db *gorm.DB, inputCharacter uint) { + db.Where("id = ?", inputCharacter).Take(&character) character.getAssociations(db) } -func (character Character) Update(db *gorm.DB) error { +func (character Character) update(db *gorm.DB) error { + // Get the original Character object var originalCharacter Character - originalCharacter.Get(db, character.Name) + result := db.Model(&Character{}).Where("id = ?", character.Model.ID).Take(&originalCharacter) + if result.Error != nil { + return result.Error + } + // Set the static values + originalCharacter.Name = character.Name + // Set the associated values by grabbing them from the database ownersError := db.Model(&originalCharacter).Association("Owners").Replace(&character.Owners) if ownersError != nil { return ownersError @@ -59,59 +99,127 @@ func (character Character) Update(db *gorm.DB) error { if inventoryError != nil { return inventoryError } + result = db.Model(&originalCharacter).Update("name", originalCharacter.Name) + if result.Error != nil { + err := errors.New("new name already exists") + return err + } + db.Save(&originalCharacter) return nil } -func (character Character) Delete(db *gorm.DB) error { - result := db.Delete(&character) +func (character Character) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&character) if result.Error != nil { return result.Error } return nil } -func Create(db *gorm.DB, name string, owners []uint, roles []string, functionsets []uint, inventory []uint) error { +func Create(db *gorm.DB, params CharacterParams) error { + var newOwners []person.Person + if len(params.Owners) > 0 { + newOwners = *person.Get(db, params.Owners) + } + var newRoles []role.Role + if len(params.Roles) > 0 { + newOwners = *person.Get(db, params.Roles) + } + var newFunctionSets []functionset.FunctionSet + if len(params.FunctionSets) > 0 { + newOwners = *person.Get(db, params.FunctionSets) + } + var newInventory []inventoryslot.InventorySlot + if len(params.Inventory) > 0 { + newOwners = *person.Get(db, params.Inventory) + } return Character{ - Name: name, - Owners: *person.Get(db, owners), - Roles: *role.Get(db, roles), - FunctionSets: *functionset.Get(db, functionsets), - Inventory: *inventoryslot.Get(db, inventory), - }.Create(db) + Name: params.Name, + Owners: newOwners, + Roles: newRoles, + FunctionSets: newFunctionSets, + Inventory: newInventory, + }.create(db) } -func Get(db *gorm.DB, inputCharacters []string) *[]Character { +func Get(db *gorm.DB, inputCharacters []uint) *[]Character { var outputCharacters []Character + if len(inputCharacters) < 1 { + db.Model(&Character{}).Select("id").Find(&inputCharacters) + } for _, inputCharacter := range inputCharacters { var outputCharacter Character - outputCharacter.Get(db, inputCharacter) + outputCharacter.get(db, inputCharacter) outputCharacters = append(outputCharacters, outputCharacter) } return &outputCharacters } -func GetAll(db *gorm.DB) *[]Character { - var outputCharacterNames []string - result := db.Model(&Character{}).Select("name").Find(&outputCharacterNames) - if result.Error != nil { - log.Println(result.Error) +func Update(db *gorm.DB, params CharacterParams) error { + var newOwners []person.Person + if len(params.Owners) > 0 { + newOwners = *person.Get(db, params.Owners) + } + var newRoles []role.Role + if len(params.Roles) > 0 { + newOwners = *person.Get(db, params.Roles) + } + var newFunctionSets []functionset.FunctionSet + if len(params.FunctionSets) > 0 { + newOwners = *person.Get(db, params.FunctionSets) + } + var newInventory []inventoryslot.InventorySlot + if len(params.Inventory) > 0 { + newOwners = *person.Get(db, params.Inventory) } - return Get(db, outputCharacterNames) -} - -func Update(db *gorm.DB, name string, owners []uint, roles []string, functionsets []uint, inventory []uint) error { return Character{ - Name: name, - Owners: *person.Get(db, owners), - Roles: *role.Get(db, roles), - FunctionSets: *functionset.Get(db, functionsets), - Inventory: *inventoryslot.Get(db, inventory), - }.Update(db) + Name: params.Name, + Owners: newOwners, + Roles: newRoles, + FunctionSets: newFunctionSets, + Inventory: newInventory, + }.update(db) } -func Delete(db *gorm.DB, inputCharacters []string) { - characters := Get(db, inputCharacters) - for _, character := range *characters { - character.Delete(db) +func Delete(db *gorm.DB, inputCharacters []uint) error { + var characters []Character + // if len(inputCharacters) < 1 { + // result := db.Model(&Character{}).Select("id").Find(&inputCharacters) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputCharacter := range inputCharacters { + var character Character + character.get(db, inputCharacter) + characters = append(characters, character) } + for _, character := range characters { + err := character.delete(db) + if err != nil { + return err + } + } + return nil +} + +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]Character, error) { + var err error + var params CharacterParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]Character + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err } diff --git a/src/lib/database/customization/customization.go b/src/lib/database/customization/customization.go index af2250b..ac5ed38 100644 --- a/src/lib/database/customization/customization.go +++ b/src/lib/database/customization/customization.go @@ -1,7 +1,8 @@ package customization import ( - "log" + "encoding/json" + "errors" function "example.com/database/function" group "example.com/database/group" @@ -12,7 +13,7 @@ import ( type Customization struct { gorm.Model - Name string `gorm:"primaryKey uniqueIndex" json:"name"` + Name string `gorm:"uniqueIndex" json:"name"` Functions []function.Function `gorm:"many2many:customization_function_associations" json:"functions"` FlavorText string `json:"flavor_text"` RulesDescription string `json:"rules_description"` @@ -21,7 +22,43 @@ type Customization struct { Visibility []group.Group `gorm:"many2many:customization_visibility_associations" json:"visibility"` // Unique } -func (customization Customization) Create(db *gorm.DB) error { +type CustomizationParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + Name string `json:"name"` + Functions []uint `json:"functions"` + FlavorText string `json:"flavor_text"` + RulesDescription string `json:"rules_description"` + PhysrepRequirements string `json:"physrep_requirements"` + Tags []uint `json:"tags"` + Visibility []uint `json:"visibility"` +} + +func (params *CustomizationParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams CustomizationParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + if inputParams.Name == "" { + return errors.New("input name cannot be empty") + } + params.Name = inputParams.Name + params.Functions = inputParams.Functions + params.FlavorText = inputParams.FlavorText + params.RulesDescription = inputParams.RulesDescription + params.PhysrepRequirements = inputParams.PhysrepRequirements + params.Tags = inputParams.Tags + params.Visibility = inputParams.Visibility + return nil +} + +func (customization Customization) create(db *gorm.DB) error { result := db.Create(&customization) if result.Error != nil { return result.Error @@ -35,18 +72,21 @@ func (customization *Customization) getAssociations(db *gorm.DB) { db.Model(&customization).Association("Visibility").Find(&customization.Visibility) } -func (customization *Customization) Get(db *gorm.DB, inputCustomization string) { - db.Where("name = ?", inputCustomization).Take(&customization) +func (customization *Customization) get(db *gorm.DB, inputCustomization uint) { + db.Where("id = ?", inputCustomization).Take(&customization) customization.getAssociations(db) } -func (customization Customization) Update(db *gorm.DB) error { +func (customization Customization) update(db *gorm.DB) error { + // Get the original Function object var originalCustomization Customization - db.Updates(&Customization{ - FlavorText: customization.FlavorText, - RulesDescription: customization.RulesDescription, - PhysrepRequirements: customization.PhysrepRequirements, - }) + result := db.Model(&Customization{}).Where("id = ?", customization.Model.ID).Take(&originalCustomization) + if result.Error != nil { + return result.Error + } + // Set the static values + originalCustomization.Name = customization.Name + // Set the associated values by grabbing them from the database functionsError := db.Model(&originalCustomization).Association("Functions").Replace(&customization.Functions) if functionsError != nil { return functionsError @@ -59,63 +99,123 @@ func (customization Customization) Update(db *gorm.DB) error { if visibilityError != nil { return visibilityError } + result = db.Model(&originalCustomization).Update("name", originalCustomization.Name) + if result.Error != nil { + err := errors.New("new name already exists") + return err + } + db.Save(&originalCustomization) return nil } -func (customization Customization) Delete(db *gorm.DB) error { - result := db.Delete(&customization) +func (customization Customization) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&customization) if result.Error != nil { return result.Error } return nil } -func Create(db *gorm.DB, name string, functions []uint, flavorText string, rulesDescription string, physrepRequesrements string, itemTags []string, visibility []uint) error { +func Create(db *gorm.DB, params CustomizationParams) error { + var newFunctions []function.Function + if len(params.Functions) > 0 { + newFunctions = *function.Get(db, params.Functions) + } + var newTags []itemtag.ItemTag + if len(params.Tags) > 0 { + newTags = *itemtag.Get(db, params.Tags) + } + var newVisibility []group.Group + if len(params.Visibility) > 0 { + newVisibility = *group.Get(db, params.Visibility) + } return Customization{ - Name: name, - Functions: *function.Get(db, functions), - FlavorText: flavorText, - RulesDescription: rulesDescription, - PhysrepRequirements: physrepRequesrements, - Tags: *itemtag.Get(db, itemTags), - Visibility: *group.Get(db, visibility), - }.Create(db) + Name: params.Name, + Functions: newFunctions, + FlavorText: params.FlavorText, + RulesDescription: params.RulesDescription, + PhysrepRequirements: params.PhysrepRequirements, + Tags: newTags, + Visibility: newVisibility, + }.create(db) } -func Get(db *gorm.DB, inputCustomizations []string) *[]Customization { +func Get(db *gorm.DB, inputCustomizations []uint) *[]Customization { var outputCustomizations []Customization + if len(inputCustomizations) < 1 { + db.Model(&Customization{}).Select("id").Find(&inputCustomizations) + } for _, inputCustomization := range inputCustomizations { var outputCustomization Customization - outputCustomization.Get(db, inputCustomization) + outputCustomization.get(db, inputCustomization) outputCustomizations = append(outputCustomizations, outputCustomization) } return &outputCustomizations } -func GetAll(db *gorm.DB) *[]Customization { - var outputCustomizationNames []string - result := db.Model(&Customization{}).Select("name").Find(&outputCustomizationNames) - if result.Error != nil { - log.Println(result.Error) +func Update(db *gorm.DB, params CustomizationParams) error { + var newFunctions []function.Function + if len(params.Functions) > 0 { + newFunctions = *function.Get(db, params.Functions) + } + var newTags []itemtag.ItemTag + if len(params.Tags) > 0 { + newTags = *itemtag.Get(db, params.Tags) + } + var newVisibility []group.Group + if len(params.Visibility) > 0 { + newVisibility = *group.Get(db, params.Visibility) } - return Get(db, outputCustomizationNames) -} - -func Update(db *gorm.DB, name string, functions []uint, flavorText string, rulesDescription string, physrepRequesrements string, itemTags []string, visibility []uint) error { return Customization{ - Name: name, - Functions: *function.Get(db, functions), - FlavorText: flavorText, - RulesDescription: rulesDescription, - PhysrepRequirements: physrepRequesrements, - Tags: *itemtag.Get(db, itemTags), - Visibility: *group.Get(db, visibility), - }.Update(db) + Name: params.Name, + Functions: newFunctions, + FlavorText: params.FlavorText, + RulesDescription: params.RulesDescription, + PhysrepRequirements: params.PhysrepRequirements, + Tags: newTags, + Visibility: newVisibility, + }.update(db) } -func Delete(db *gorm.DB, inputCustomizations []string) { - customizations := Get(db, inputCustomizations) - for _, customization := range *customizations { - customization.Delete(db) +func Delete(db *gorm.DB, inputCustomizations []uint) error { + var customizations []Customization + // if len(inputCustomizations) < 1 { + // result := db.Model(&Customization{}).Select("id").Find(&inputCustomizations) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputCustomization := range inputCustomizations { + var customization Customization + customization.get(db, inputCustomization) + customizations = append(customizations, customization) } + for _, customization := range customizations { + err := customization.delete(db) + if err != nil { + return err + } + } + return nil +} + +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]Customization, error) { + var err error + var params CustomizationParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]Customization + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err } diff --git a/src/lib/database/function/function.go b/src/lib/database/function/function.go index 0230e33..1e4047c 100644 --- a/src/lib/database/function/function.go +++ b/src/lib/database/function/function.go @@ -3,12 +3,8 @@ package function import ( "encoding/json" "errors" - "io" - "log" - "strconv" functiontag "example.com/database/functiontag" - "github.com/gin-gonic/gin" "gorm.io/gorm" ) @@ -20,14 +16,35 @@ type Function struct { Requirements []Function `gorm:"many2many:function_requirement_associations" json:"requirements"` } -type functionParams struct { - Id string `json:"id"` +type FunctionParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields Name string `json:"name"` Tags []uint `json:"tags"` Requirements []uint `json:"requirements"` } -func (function Function) Create(db *gorm.DB) error { +func (params *FunctionParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams FunctionParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + if inputParams.Name == "" { + return errors.New("input name cannot be empty") + } + params.Name = inputParams.Name + params.Tags = inputParams.Tags + params.Requirements = inputParams.Requirements + return nil +} + +func (function Function) create(db *gorm.DB) error { result := db.Create(&function) if result.Error != nil { return result.Error @@ -40,39 +57,21 @@ func (function *Function) getAssociations(db *gorm.DB) { db.Model(&function).Association("Requirements").Find(&function.Requirements) } -func (params *functionParams) validate(context *gin.Context) error { - ID, IDOk := context.GetQuery("id") - if !IDOk { - return errors.New("ID was not included in the request") - } - body, err := io.ReadAll(context.Request.Body) - if err != nil { - log.Println(err) - return err - } - log.Println(string(body)) - var newParams functionParams - err = json.Unmarshal(body, &newParams) - log.Println(err, newParams) - params.Id = ID - params.Name = newParams.Name - params.Tags = newParams.Tags - params.Requirements = newParams.Requirements - return nil -} - -func (function *Function) Get(db *gorm.DB, inputFunction uint) { +func (function *Function) get(db *gorm.DB, inputFunction uint) { db.Where("id = ?", inputFunction).Take(&function) function.getAssociations(db) } func (function Function) update(db *gorm.DB) error { + // Get the original Function object var originalFunction Function result := db.Model(&Function{}).Where("id = ?", function.Model.ID).Take(&originalFunction) if result.Error != nil { return result.Error } + // Set the static values originalFunction.Name = function.Name + // Set the associated values by grabbing them from the database tagsError := db.Model(&originalFunction).Association("Tags").Replace(&function.Tags) if tagsError != nil { return tagsError @@ -81,76 +80,108 @@ func (function Function) update(db *gorm.DB) error { if requirementsError != nil { return requirementsError } + result = db.Model(&originalFunction).Update("name", originalFunction.Name) + if result.Error != nil { + err := errors.New("new name already exists") + return err + } db.Save(&originalFunction) return nil } -func (function Function) Delete(db *gorm.DB) error { - result := db.Delete(&function) +func (function Function) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&function) if result.Error != nil { return result.Error } return nil } -func Create(db *gorm.DB, context *gin.Context) error { - var params functionParams - err := params.validate(context) - if err != nil { - return err +func Create(db *gorm.DB, params FunctionParams) error { + var newTags []functiontag.FunctionTag + if len(params.Tags) > 0 { + newTags = *functiontag.Get(db, params.Tags) + } + var newRequirements []Function + if len(params.Requirements) > 0 { + newRequirements = *Get(db, params.Requirements) } return Function{ Name: params.Name, - Tags: *functiontag.Get(db, params.Tags), - Requirements: *Get(db, params.Requirements), - }.Create(db) + Tags: newTags, + Requirements: newRequirements, + }.create(db) } func Get(db *gorm.DB, inputFunctions []uint) *[]Function { var outputFunctions []Function + if len(inputFunctions) < 1 { + db.Model(&Function{}).Select("id").Find(&inputFunctions) + } for _, inputFunction := range inputFunctions { var outputFunction Function - outputFunction.Get(db, inputFunction) + outputFunction.get(db, inputFunction) outputFunctions = append(outputFunctions, outputFunction) } - log.Println(outputFunctions) return &outputFunctions } -func GetAll(db *gorm.DB) *[]Function { - var outputFunctionNames []uint - result := db.Model(&Function{}).Select("id").Find(&outputFunctionNames) - if result.Error != nil { - log.Println(result.Error) +func Update(db *gorm.DB, params FunctionParams) error { + var newTags []functiontag.FunctionTag + if len(params.Tags) > 0 { + newTags = *functiontag.Get(db, params.Tags) } - return Get(db, outputFunctionNames) -} - -func Update(db *gorm.DB, context *gin.Context) error { - var params functionParams - err := params.validate(context) - if err != nil { - return err - } - uintID, err := strconv.Atoi(params.Id) - if err != nil { - return err + var newRequirements []Function + if len(params.Requirements) > 0 { + newRequirements = *Get(db, params.Requirements) } return Function{ - Model: gorm.Model{ID: uint(uintID)}, + Model: gorm.Model{ID: params.IDArray[0]}, Name: params.Name, - Tags: *functiontag.Get(db, params.Tags), - Requirements: *Get(db, params.Requirements), + Tags: newTags, + Requirements: newRequirements, }.update(db) } func Delete(db *gorm.DB, inputFunctions []uint) error { - functions := Get(db, inputFunctions) - for _, function := range *functions { - err := function.Delete(db) + var functions []Function + // if len(inputFunctions) < 1 { + // result := db.Model(&Function{}).Select("id").Find(&inputFunctions) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputFunction := range inputFunctions { + var function Function + function.get(db, inputFunction) + functions = append(functions, function) + } + for _, function := range functions { + err := function.delete(db) if err != nil { return err } } return nil } + +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]Function, error) { + var err error + var params FunctionParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]Function + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err +} diff --git a/src/lib/database/functionset/functionset.go b/src/lib/database/functionset/functionset.go index ec51de8..f1f65bf 100644 --- a/src/lib/database/functionset/functionset.go +++ b/src/lib/database/functionset/functionset.go @@ -1,7 +1,7 @@ package functionset import ( - "log" + "encoding/json" function "example.com/database/function" @@ -13,7 +13,28 @@ type FunctionSet struct { Functions []function.Function `gorm:"many2many:functionset_function_associations" json:"functions"` } -func (functionSet FunctionSet) Create(db *gorm.DB) error { +type FunctionSetParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + Functions []uint `json:"functions"` +} + +func (params *FunctionSetParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams FunctionSetParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + params.Functions = inputParams.Functions + return nil +} + +func (functionSet FunctionSet) create(db *gorm.DB) error { result := db.Create(&functionSet) if result.Error != nil { return result.Error @@ -25,63 +46,107 @@ func (functionSet *FunctionSet) getAssociations(db *gorm.DB) { db.Model(&functionSet).Association("Functions").Find(&functionSet.Functions) } -func (functionSet *FunctionSet) Get(db *gorm.DB, inputFunctionSet uint) { +func (functionSet *FunctionSet) get(db *gorm.DB, inputFunctionSet uint) { db.Where("id = ?", inputFunctionSet).Take(&functionSet) functionSet.getAssociations(db) } -func (functionSet FunctionSet) Update(db *gorm.DB) error { - result := db.Save(&functionSet) +func (functionSet FunctionSet) update(db *gorm.DB) error { + // Get the original FunctionSet object + var originalFunctionSet FunctionSet + result := db.Model(&FunctionSet{}).Where("id = ?", functionSet.Model.ID).Take(&originalFunctionSet) + if result.Error != nil { + return result.Error + } + // Set the associated values by grabbing them from the database + tagsError := db.Model(&originalFunctionSet).Association("Functions").Replace(&functionSet.Functions) + if tagsError != nil { + return tagsError + } + db.Save(&originalFunctionSet) + return nil +} + +func (functionSet FunctionSet) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&functionSet) if result.Error != nil { return result.Error } return nil } -func (functionSet FunctionSet) Delete(db *gorm.DB) error { - result := db.Delete(&functionSet) - if result.Error != nil { - return result.Error +func Create(db *gorm.DB, params FunctionSetParams) error { + var newFunctions []function.Function + if len(params.Functions) > 0 { + newFunctions = *function.Get(db, params.Functions) } - return nil -} - -func Create(db *gorm.DB, functions []uint) error { return FunctionSet{ - Functions: *function.Get(db, functions), - }.Create(db) + Functions: newFunctions, + }.create(db) } func Get(db *gorm.DB, inputFunctionSets []uint) *[]FunctionSet { var outputFunctionSets []FunctionSet + if len(inputFunctionSets) < 1 { + db.Model(&FunctionSet{}).Select("id").Find(&inputFunctionSets) + } for _, inputFunctionSet := range inputFunctionSets { var outputFunctionSet FunctionSet - outputFunctionSet.Get(db, inputFunctionSet) + outputFunctionSet.get(db, inputFunctionSet) outputFunctionSets = append(outputFunctionSets, outputFunctionSet) } return &outputFunctionSets } -func GetAll(db *gorm.DB) *[]FunctionSet { - var outputFunctionSetIDs []uint - result := db.Model(&FunctionSet{}).Select("id").Find(&outputFunctionSetIDs) - if result.Error != nil { - log.Println(result.Error) +func Update(db *gorm.DB, params FunctionSetParams) error { + var newFunctions []function.Function + if len(params.Functions) > 0 { + newFunctions = *function.Get(db, params.Functions) } - return Get(db, outputFunctionSetIDs) + return FunctionSet{ + Functions: newFunctions, + }.update(db) } -func Update(db *gorm.DB, id int, functions []uint) error { - outputFunctionSet := FunctionSet{ - Functions: *function.Get(db, functions), +func Delete(db *gorm.DB, inputFunctionSets []uint) error { + var functionSets []FunctionSet + // if len(inputFunctionSets) < 1 { + // result := db.Model(&FunctionSet{}).Select("id").Find(&inputFunctionSets) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputFunctionSet := range inputFunctionSets { + var functionSet FunctionSet + functionSet.get(db, inputFunctionSet) + functionSets = append(functionSets, functionSet) } - outputFunctionSet.ID = uint(id) - return outputFunctionSet.Update(db) + for _, function := range functionSets { + err := function.delete(db) + if err != nil { + return err + } + } + return nil } -func Delete(db *gorm.DB, inputFunctionSets []uint) { - functionSets := Get(db, inputFunctionSets) - for _, functionSet := range *functionSets { - functionSet.Delete(db) +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]FunctionSet, error) { + var err error + var params FunctionSetParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err } + var result *[]FunctionSet + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err } diff --git a/src/lib/database/functiontag/functiontag.go b/src/lib/database/functiontag/functiontag.go index a2255b0..0fd39a2 100644 --- a/src/lib/database/functiontag/functiontag.go +++ b/src/lib/database/functiontag/functiontag.go @@ -3,11 +3,7 @@ package functiontag import ( "encoding/json" "errors" - "io" - "log" - "strconv" - "github.com/gin-gonic/gin" "gorm.io/gorm" ) @@ -16,27 +12,35 @@ type FunctionTag struct { Name string `gorm:"uniqueIndex" json:"name"` } -type functionTagParams struct { +type FunctionTagParams struct { // ID of the object being modified - ID string + IDArray []uint `json:"id"` // New fields - Name string + Name string `json:"name"` } -func (params *functionTagParams) validate(context *gin.Context) error { - ID, IDOk := context.GetQuery("id") - if !IDOk { - return errors.New("ID was not included in the request") +func (params *FunctionTagParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams FunctionTagParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil } - body, err := io.ReadAll(context.Request.Body) + err := json.Unmarshal(*body, &inputParams) if err != nil { - log.Println(err) return err } - var name functionTagParams - _ = json.Unmarshal(body, &name) - params.ID = ID - params.Name = name.Name + if inputParams.Name == "" { + return errors.New("input name cannot be empty") + } + params.Name = inputParams.Name + return nil +} + +func (functionTag FunctionTag) create(db *gorm.DB) error { + result := db.Create(&functionTag) + if result.Error != nil { + return result.Error + } return nil } @@ -51,43 +55,34 @@ func (functionTag FunctionTag) update(db *gorm.DB) error { return result.Error } originalFunctionTag.Name = functionTag.Name + result = db.Model(&originalFunctionTag).Update("name", originalFunctionTag.Name) + if result.Error != nil { + err := errors.New("new name already exists") + return err + } db.Save(&originalFunctionTag) return nil } -func (functionTag FunctionTag) create(db *gorm.DB) error { - result := db.Create(&functionTag) - if result.Error != nil { - return result.Error - } - return nil -} - func (functionTag FunctionTag) delete(db *gorm.DB) error { - result := db.Delete(&functionTag) + result := db.Unscoped().Delete(&functionTag) if result.Error != nil { return result.Error } return nil } -func Create(db *gorm.DB, context *gin.Context) error { - body, err := io.ReadAll(context.Request.Body) - if err != nil { - return err - } - var newFunctionTag FunctionTag - err = json.Unmarshal(body, &newFunctionTag) - if err != nil { - return err - } +func Create(db *gorm.DB, params FunctionTagParams) error { return FunctionTag{ - Name: newFunctionTag.Name, + Name: params.Name, }.create(db) } func Get(db *gorm.DB, inputFunctionTags []uint) *[]FunctionTag { var outputFunctionTags []FunctionTag + if len(inputFunctionTags) < 1 { + db.Model(&FunctionTag{}).Select("id").Find(&inputFunctionTags) + } for _, inputFunctionTag := range inputFunctionTags { var outputFunctionTag FunctionTag outputFunctionTag.get(db, inputFunctionTag) @@ -96,40 +91,52 @@ func Get(db *gorm.DB, inputFunctionTags []uint) *[]FunctionTag { return &outputFunctionTags } -func GetAll(db *gorm.DB) *[]FunctionTag { - var outputFunctionTags []FunctionTag - var outputFunctionTagIDs []uint - result := db.Model(&FunctionTag{}).Select("id").Find(&outputFunctionTagIDs) - if result.Error != nil { - log.Println(result.Error) - } - outputFunctionTags = *Get(db, outputFunctionTagIDs) - return &outputFunctionTags -} - -func Update(db *gorm.DB, context *gin.Context) error { - var params functionTagParams - err := params.validate(context) - if err != nil { - return err - } - uintID, err := strconv.Atoi(params.ID) - if err != nil { - return err - } +func Update(db *gorm.DB, params FunctionTagParams) error { return FunctionTag{ - Model: gorm.Model{ID: uint(uintID)}, + Model: gorm.Model{ID: params.IDArray[0]}, Name: params.Name, }.update(db) } func Delete(db *gorm.DB, inputFunctionTags []uint) error { - functionTags := Get(db, inputFunctionTags) - for _, functiontag := range *functionTags { - err := functiontag.delete(db) + var functionTags []FunctionTag + // if len(inputFunctionTags) < 1 { + // result := db.Model(&FunctionTag{}).Select("id").Find(&inputFunctionTags) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputFunctionTag := range inputFunctionTags { + var functionTag FunctionTag + functionTag.get(db, inputFunctionTag) + functionTags = append(functionTags, functionTag) + } + for _, functionTag := range functionTags { + err := functionTag.delete(db) if err != nil { return err } } return nil } + +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]FunctionTag, error) { + var err error + var params FunctionTagParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]FunctionTag + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err +} diff --git a/src/lib/database/group/group.go b/src/lib/database/group/group.go index dd6994e..918c4e3 100644 --- a/src/lib/database/group/group.go +++ b/src/lib/database/group/group.go @@ -3,12 +3,7 @@ package group import ( "encoding/json" "errors" - "io" - "net/http" - "slices" - "strconv" - "github.com/gin-gonic/gin" "gorm.io/gorm" ) @@ -17,26 +12,35 @@ type Group struct { Name string `gorm:"uniqueIndex" json:"name"` } -type groupParams struct { - // ID of the object being modified - ID string +type GroupParams struct { + // ID(s) of the object being modified + IDArray []uint // New fields Name string } -func (params *groupParams) validate(context *gin.Context) error { - ID, IDOk := context.GetQuery("id") - if !IDOk && slices.Contains([]string{"PUT"}, context.Request.Method) { - return errors.New("ID was not included in the request") +func (params *GroupParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams GroupParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil } - body, err := io.ReadAll(context.Request.Body) + err := json.Unmarshal(*body, &inputParams) if err != nil { return err } - var name groupParams - _ = json.Unmarshal(body, &name) - params.ID = ID - params.Name = name.Name + if inputParams.Name == "" { + return errors.New("input name cannot be empty") + } + params.Name = inputParams.Name + return nil +} + +func (group Group) create(db *gorm.DB) error { + result := db.Create(&group) + if result.Error != nil { + return result.Error + } return nil } @@ -51,6 +55,11 @@ func (group Group) update(db *gorm.DB) error { return result.Error } originalGroup.Name = group.Name + result = db.Model(&originalGroup).Update("name", originalGroup.Name) + if result.Error != nil { + err := errors.New("new name already exists") + return err + } db.Save(&originalGroup) return nil } @@ -63,15 +72,7 @@ func (group Group) delete(db *gorm.DB) error { return nil } -func (group Group) create(db *gorm.DB) error { - result := db.Create(&group) - if result.Error != nil { - return result.Error - } - return nil -} - -func Create(db *gorm.DB, params groupParams) error { +func Create(db *gorm.DB, params GroupParams) error { return Group{ Name: params.Name, }.create(db) @@ -90,13 +91,9 @@ func Get(db *gorm.DB, inputGroups []uint) *[]Group { return &outputGroups } -func Update(db *gorm.DB, params groupParams) error { - uintID, err := strconv.Atoi(params.ID) - if err != nil { - return err - } +func Update(db *gorm.DB, params GroupParams) error { return Group{ - Model: gorm.Model{ID: uint(uintID)}, + Model: gorm.Model{ID: params.IDArray[0]}, Name: params.Name, }.update(db) } @@ -123,33 +120,23 @@ func Delete(db *gorm.DB, inputGroups []uint) error { return nil } -func HandleRequest(db *gorm.DB, context *gin.Context) error { - var params groupParams - if err := params.validate(context); err != nil { - return err - } - idArray, _ := context.GetQueryArray("id") - var idUintArray []uint - for _, id := range idArray { - idUint, err := strconv.Atoi(id) - if err != nil { - return err - } - idUintArray = append(idUintArray, uint(idUint)) - } +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]Group, error) { var err error - switch context.Request.Method { + var params GroupParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]Group + switch method { case "GET": - result := Get(db, idUintArray) - context.JSON(http.StatusOK, gin.H{ - "result": result, - }) + result = Get(db, params.IDArray) case "POST": err = Create(db, params) case "PUT": err = Update(db, params) case "DELETE": - err = Delete(db, idUintArray) + err = Delete(db, params.IDArray) } - return err + return result, err } diff --git a/src/lib/database/inventoryslot/inventoryslot.go b/src/lib/database/inventoryslot/inventoryslot.go index 0c6a117..06e3488 100644 --- a/src/lib/database/inventoryslot/inventoryslot.go +++ b/src/lib/database/inventoryslot/inventoryslot.go @@ -1,7 +1,8 @@ package inventoryslot import ( - "log" + "encoding/json" + "errors" item "example.com/database/item" @@ -10,11 +11,34 @@ import ( type InventorySlot struct { gorm.Model - Item item.Item `gorm:"foreignKey:Name" json:"item"` + Item item.Item `gorm:"uniqueIndex foreignKey:Name" json:"item"` Quantity int64 `json:"quantity"` // Positive } -func (inventorySlot InventorySlot) Create(db *gorm.DB) error { +type InventorySlotParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + Item uint `json:"item"` + Quantity int64 `json:"quantity"` +} + +func (params *InventorySlotParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams InventorySlotParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + params.Item = inputParams.Item + params.Quantity = inputParams.Quantity + return nil +} + +func (inventorySlot InventorySlot) create(db *gorm.DB) error { result := db.Create(&inventorySlot) if result.Error != nil { return result.Error @@ -27,68 +51,112 @@ func (inventorySlot *InventorySlot) getAssociations(db *gorm.DB) { } -func (inventorySlot *InventorySlot) Get(db *gorm.DB, inputInventorySlot uint) { +func (inventorySlot *InventorySlot) get(db *gorm.DB, inputInventorySlot uint) { db.Where("id = ?", inputInventorySlot).Take(&inventorySlot) inventorySlot.getAssociations(db) } -func (inventorySlot InventorySlot) Update(db *gorm.DB) error { - var originalIventorySlot InventorySlot - originalIventorySlot.Get(db, inventorySlot.ID) - itemsError := db.Model(&originalIventorySlot).Association("Item").Replace(&inventorySlot.Item) +func (inventorySlot InventorySlot) update(db *gorm.DB) error { + // Get the original InventorySlot object + var originalInventorySlot InventorySlot + result := db.Model(&InventorySlot{}).Where("id = ?", inventorySlot.Model.ID).Take(&originalInventorySlot) + if result.Error != nil { + return result.Error + } + // Set the static values + originalInventorySlot.Quantity = inventorySlot.Quantity + // Set the associated values by grabbing them from the database + itemsError := db.Model(&originalInventorySlot).Association("Item").Replace(&inventorySlot.Item) if itemsError != nil { return itemsError } - originalIventorySlot.Quantity = inventorySlot.Quantity + result = db.Model(&originalInventorySlot).Update("item", originalInventorySlot.Item) + if result.Error != nil { + err := errors.New("new item already exists") + return err + } + db.Save(&originalInventorySlot) return nil } -func (inventorySlot InventorySlot) Delete(db *gorm.DB) error { - result := db.Delete(&inventorySlot) +func (inventorySlot InventorySlot) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&inventorySlot) if result.Error != nil { return result.Error } return nil } -func Create(db *gorm.DB, itemName string, quantity int64) error { +func Create(db *gorm.DB, params InventorySlotParams) error { + var newItem item.Item + newItem = (*item.Get(db, []uint{params.Item}))[0] return InventorySlot{ - Item: (*item.Get(db, []string{itemName}))[0], - Quantity: quantity, - }.Create(db) + Item: newItem, + Quantity: params.Quantity, + }.create(db) } func Get(db *gorm.DB, inputInventorySlots []uint) *[]InventorySlot { var outputInventorySlots []InventorySlot + if len(inputInventorySlots) < 1 { + db.Model(&InventorySlot{}).Select("id").Find(&inputInventorySlots) + } for _, inputInventorySlot := range inputInventorySlots { var outputInventorySlot InventorySlot - outputInventorySlot.Get(db, inputInventorySlot) + outputInventorySlot.get(db, inputInventorySlot) outputInventorySlots = append(outputInventorySlots, outputInventorySlot) } return &outputInventorySlots } -func GetAll(db *gorm.DB) *[]InventorySlot { - var outputInventorySlotIDs []uint - result := db.Model(&InventorySlot{}).Select("id").Find(&outputInventorySlotIDs) - if result.Error != nil { - log.Println(result.Error) - } - return Get(db, outputInventorySlotIDs) +func Update(db *gorm.DB, params InventorySlotParams) error { + var newItem item.Item + newItem = (*item.Get(db, []uint{params.Item}))[0] + return InventorySlot{ + Item: newItem, + Quantity: params.Quantity, + }.update(db) } -func Update(db *gorm.DB, itemID int, itemName string, quantity int64) error { - inventorySlot := InventorySlot{ - Item: (*item.Get(db, []string{itemName}))[0], - Quantity: quantity, +func Delete(db *gorm.DB, inputInventorySlots []uint) error { + var inventorySlots []InventorySlot + // if len(inputInventorySlots) < 1 { + // result := db.Model(&InventorySlot{}).Select("id").Find(&inputInventorySlots) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputInventorySlot := range inputInventorySlots { + var inventorySlot InventorySlot + inventorySlot.get(db, inputInventorySlot) + inventorySlots = append(inventorySlots, inventorySlot) } - inventorySlot.ID = uint(itemID) - return inventorySlot.Update(db) + for _, inventorySlot := range inventorySlots { + err := inventorySlot.delete(db) + if err != nil { + return err + } + } + return nil } -func Delete(db *gorm.DB, inputInventorySlotIDs []uint) { - inventorySlots := Get(db, inputInventorySlotIDs) - for _, inventorySlot := range *inventorySlots { - inventorySlot.Delete(db) +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]InventorySlot, error) { + var err error + var params InventorySlotParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err } + var result *[]InventorySlot + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err } diff --git a/src/lib/database/item/item.go b/src/lib/database/item/item.go index b6b1192..55d6bf3 100644 --- a/src/lib/database/item/item.go +++ b/src/lib/database/item/item.go @@ -1,7 +1,8 @@ package item import ( - "log" + "encoding/json" + "errors" customization "example.com/database/customization" function "example.com/database/function" @@ -23,7 +24,45 @@ type Item struct { Visibility []group.Group `gorm:"many2many:item_visibility_associations" json:"visibility"` // Unique } -func (item Item) Create(db *gorm.DB) error { +type ItemParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + Name string `json:"name"` + Functions []uint `json:"functions"` + FlavorText string `json:"flavor_text"` + RulesDescription string `json:"rules_description"` + PhysrepRequirements string `json:"phyrep_requirements"` + Tags []uint `json:"tags"` + Customizations []uint `json:"customizations"` + Visibility []uint `json:"visibility"` +} + +func (params *ItemParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams ItemParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + if inputParams.Name == "" { + return errors.New("input name cannot be empty") + } + params.Name = inputParams.Name + params.Functions = inputParams.Functions + params.FlavorText = inputParams.FlavorText + params.RulesDescription = inputParams.RulesDescription + params.PhysrepRequirements = inputParams.PhysrepRequirements + params.Tags = inputParams.Tags + params.Customizations = inputParams.Customizations + params.Visibility = inputParams.Visibility + return nil +} + +func (item Item) create(db *gorm.DB) error { result := db.Create(&item) if result.Error != nil { return result.Error @@ -31,21 +70,31 @@ func (item Item) Create(db *gorm.DB) error { return nil } -func (item Item) getAssociations(db *gorm.DB) { +func (item *Item) getAssociations(db *gorm.DB) { db.Model(&item).Association("Functions").Find(&item.Functions) db.Model(&item).Association("Tags").Find(&item.Tags) db.Model(&item).Association("Customizations").Find(&item.Customizations) db.Model(&item).Association("Visibility").Find(&item.Visibility) } -func (item Item) Get(db *gorm.DB, inputItem string) { - db.Where("name = ?", inputItem).Take(&item) +func (item *Item) get(db *gorm.DB, inputItem uint) { + db.Where("id = ?", inputItem).Take(&item) item.getAssociations(db) } -func (item Item) Update(db *gorm.DB) error { +func (item Item) update(db *gorm.DB) error { + // Get the original Item object var originalItem Item - originalItem.Get(db, item.Name) + result := db.Model(&Item{}).Where("id = ?", item.Model.ID).Take(&originalItem) + if result.Error != nil { + return result.Error + } + // Set the static values + originalItem.Name = item.Name + originalItem.FlavorText = item.FlavorText + originalItem.RulesDescription = item.RulesDescription + originalItem.PhysrepRequirements = item.PhysrepRequirements + // Set the associated values by grabbing them from the database functionsError := db.Model(&originalItem).Association("Functions").Find(&originalItem.Functions) if functionsError != nil { return functionsError @@ -62,65 +111,133 @@ func (item Item) Update(db *gorm.DB) error { if visibilityError != nil { return visibilityError } + result = db.Model(&originalItem).Update("name", originalItem.Name) + if result.Error != nil { + err := errors.New("new name already exists") + return err + } + db.Save(&originalItem) return nil } -func (item Item) Delete(db *gorm.DB) error { - result := db.Delete(&item) +func (item Item) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&item) if result.Error != nil { return result.Error } return nil } -func Create(db *gorm.DB, name string, functions []uint, flavorText string, rulesDescription string, physrepRequirements string, tags []string, customizations []string, visibility []uint) error { +func Create(db *gorm.DB, params ItemParams) error { + var newFunctions []function.Function + if len(params.Functions) > 0 { + newFunctions = *function.Get(db, params.Functions) + } + var newTags []itemtag.ItemTag + if len(params.Tags) > 0 { + newTags = *itemtag.Get(db, params.Tags) + } + var newCustomizations []customization.Customization + if len(params.Customizations) > 0 { + newCustomizations = *customization.Get(db, params.Customizations) + } + var newVisibility []group.Group + if len(params.Visibility) > 0 { + newVisibility = *group.Get(db, params.Visibility) + } return Item{ - Name: name, - Functions: *function.Get(db, functions), - FlavorText: flavorText, - RulesDescription: rulesDescription, - PhysrepRequirements: physrepRequirements, - Tags: *itemtag.Get(db, tags), - Customizations: *customization.Get(db, customizations), - Visibility: *group.Get(db, visibility), - }.Create(db) + Name: params.Name, + Functions: newFunctions, + FlavorText: params.FlavorText, + RulesDescription: params.RulesDescription, + PhysrepRequirements: params.PhysrepRequirements, + Tags: newTags, + Customizations: newCustomizations, + Visibility: newVisibility, + }.create(db) } -func Get(db *gorm.DB, inputItems []string) *[]Item { +func Get(db *gorm.DB, inputItems []uint) *[]Item { var outputItems []Item + if len(inputItems) < 1 { + db.Model(&Item{}).Select("id").Find(&inputItems) + } for _, inputItem := range inputItems { var outputItem Item - outputItem.Get(db, inputItem) + outputItem.get(db, inputItem) outputItems = append(outputItems, outputItem) } return &outputItems } -func GetAll(db *gorm.DB) *[]Item { - var outputItemNames []string - result := db.Model(&Item{}).Select("name").Find(&outputItemNames) - if result.Error != nil { - log.Println(result.Error) +func Update(db *gorm.DB, params ItemParams) error { + var newFunctions []function.Function + if len(params.Functions) > 0 { + newFunctions = *function.Get(db, params.Functions) + } + var newTags []itemtag.ItemTag + if len(params.Tags) > 0 { + newTags = *itemtag.Get(db, params.Tags) + } + var newCustomizations []customization.Customization + if len(params.Customizations) > 0 { + newCustomizations = *customization.Get(db, params.Customizations) + } + var newVisibility []group.Group + if len(params.Visibility) > 0 { + newVisibility = *group.Get(db, params.Visibility) } - return Get(db, outputItemNames) -} - -func Update(db *gorm.DB, name string, functions []uint, flavorText string, rulesDescription string, physrepRequirements string, tags []string, customizations []string, visibility []uint) error { return Item{ - Name: name, - Functions: *function.Get(db, functions), - FlavorText: flavorText, - RulesDescription: rulesDescription, - PhysrepRequirements: physrepRequirements, - Tags: *itemtag.Get(db, tags), - Customizations: *customization.Get(db, customizations), - Visibility: *group.Get(db, visibility), - }.Update(db) + Name: params.Name, + Functions: newFunctions, + FlavorText: params.FlavorText, + RulesDescription: params.RulesDescription, + PhysrepRequirements: params.PhysrepRequirements, + Tags: newTags, + Customizations: newCustomizations, + Visibility: newVisibility, + }.update(db) } -func Delete(db *gorm.DB, inputItem []string) { - items := Get(db, inputItem) - for _, item := range *items { - item.Delete(db) +func Delete(db *gorm.DB, inputItems []uint) error { + var items []Item + // if len(inputItem) < 1 { + // result := db.Model(&Item{}).Select("id").Find(&inputItem) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputItem := range inputItems { + var item Item + item.get(db, inputItem) + items = append(items, item) } + for _, item := range items { + err := item.delete(db) + if err != nil { + return err + } + } + return nil +} + +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]Item, error) { + var err error + var params ItemParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]Item + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err } diff --git a/src/lib/database/itemtag/itemtag.go b/src/lib/database/itemtag/itemtag.go index 9cf6d23..8c065ad 100644 --- a/src/lib/database/itemtag/itemtag.go +++ b/src/lib/database/itemtag/itemtag.go @@ -1,17 +1,42 @@ package itemtag import ( - "log" + "encoding/json" + "errors" "gorm.io/gorm" ) type ItemTag struct { gorm.Model - Name string `gorm:"primaryKey uniqueIndex" json:"name"` + Name string `gorm:"uniqueIndex" json:"name"` } -func (itemTag ItemTag) Create(db *gorm.DB) error { +type ItemTagParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + Name string `json:"name"` +} + +func (params *ItemTagParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams ItemTagParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + if inputParams.Name == "" { + return errors.New("input name cannot be empty") + } + params.Name = inputParams.Name + return nil +} + +func (itemTag ItemTag) create(db *gorm.DB) error { result := db.Create(&itemTag) if result.Error != nil { return result.Error @@ -19,60 +44,100 @@ func (itemTag ItemTag) Create(db *gorm.DB) error { return nil } -func (itemTag *ItemTag) Get(db *gorm.DB, inputItemTag string) { - db.Where("name = ?", inputItemTag).Take(&itemTag) +func (itemTag *ItemTag) get(db *gorm.DB, inputItemTag uint) { + db.Where("id = ?", inputItemTag).Take(&itemTag) } -func (itemTag ItemTag) Update(db *gorm.DB) error { - result := db.Save(&itemTag) +func (itemTag ItemTag) update(db *gorm.DB) error { + // Get the original Function object + var originalItemTag ItemTag + result := db.Model(&ItemTag{}).Where("id = ?", itemTag.Model.ID).Take(&originalItemTag) + if result.Error != nil { + return result.Error + } + // Set the static values + originalItemTag.Name = itemTag.Name + result = db.Model(&originalItemTag).Update("name", originalItemTag.Name) + if result.Error != nil { + err := errors.New("new name already exists") + return err + } + db.Save(&originalItemTag) + return nil +} + +func (itemTag ItemTag) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&itemTag) if result.Error != nil { return result.Error } return nil } -func (itemTag ItemTag) Delete(db *gorm.DB) error { - result := db.Delete(&itemTag) - if result.Error != nil { - return result.Error - } - return nil -} - -func Create(db *gorm.DB, name string) error { +func Create(db *gorm.DB, params ItemTagParams) error { return ItemTag{ - Name: name, - }.Create(db) + Name: params.Name, + }.create(db) } -func Get(db *gorm.DB, inputItemTags []string) *[]ItemTag { +func Get(db *gorm.DB, inputItemTags []uint) *[]ItemTag { var outputItemTags []ItemTag + if len(inputItemTags) < 1 { + db.Model(&ItemTag{}).Select("id").Find(&inputItemTags) + } for _, inputItemTag := range inputItemTags { var outputItemTag ItemTag - outputItemTag.Get(db, inputItemTag) + outputItemTag.get(db, inputItemTag) outputItemTags = append(outputItemTags, outputItemTag) } return &outputItemTags } -func GetAll(db *gorm.DB) *[]ItemTag { - var outputItemTagNames []string - result := db.Model(&ItemTag{}).Select("name").Find(&outputItemTagNames) - if result.Error != nil { - log.Println(result.Error) - } - return Get(db, outputItemTagNames) -} - -func Update(db *gorm.DB, name string) error { +func Update(db *gorm.DB, params ItemTagParams) error { return ItemTag{ - Name: name, - }.Update(db) + Name: params.Name, + }.update(db) } -func Delete(db *gorm.DB, inputItemTags []string) { - itemtags := Get(db, inputItemTags) - for _, itemtag := range *itemtags { - itemtag.Delete(db) +func Delete(db *gorm.DB, inputItemTags []uint) error { + var itemTags []ItemTag + // if len(inputItemTags) < 1 { + // result := db.Model(&ItemTag{}).Select("id").Find(&inputItemTags) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputItemTag := range inputItemTags { + var itemTag ItemTag + itemTag.get(db, inputItemTag) + itemTags = append(itemTags, itemTag) } + for _, itemTag := range itemTags { + err := itemTag.delete(db) + if err != nil { + return err + } + } + return nil +} + +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]ItemTag, error) { + var err error + var params ItemTagParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]ItemTag + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err } diff --git a/src/lib/database/person/person.go b/src/lib/database/person/person.go index 3cbbc8f..8f5bc07 100644 --- a/src/lib/database/person/person.go +++ b/src/lib/database/person/person.go @@ -1,6 +1,8 @@ package person import ( + "encoding/json" + "errors" "log" group "example.com/database/group" @@ -14,7 +16,33 @@ type Person struct { Groups []group.Group `gorm:"many2many:person_group_associations" json:"groups"` // Unique } -func (person Person) Create(db *gorm.DB) error { +type PersonParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + Name string `json:"name"` + Groups []uint `json:"groups"` +} + +func (params *PersonParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams PersonParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + if inputParams.Name == "" { + return errors.New("input name cannot be empty") + } + params.Name = inputParams.Name + params.Groups = inputParams.Groups + return nil +} + +func (person Person) create(db *gorm.DB) error { result := db.Create(&person) if result.Error != nil { return result.Error @@ -26,34 +54,52 @@ func (person *Person) getAssociations(db *gorm.DB) { db.Model(&person).Association("Groups").Find(&person.Groups) } -func (person *Person) Get(db *gorm.DB, inputPerson uint) { +func (person *Person) get(db *gorm.DB, inputPerson uint) { db.Where("id = ?", inputPerson).Take(&person) person.getAssociations(db) } -func (person Person) Update(db *gorm.DB) error { +func (person Person) update(db *gorm.DB) error { + // Get the original Person object var originalPerson Person - originalPerson.Get(db, person.ID) + result := db.Model(&Person{}).Where("id = ?", person.Model.ID).Take(&originalPerson) + if result.Error != nil { + return result.Error + } + // Set the static values + originalPerson.Name = person.Name + // Set the associated values by grabbing them from the database groupsError := db.Model(&originalPerson).Association("Groups").Replace(&person.Groups) if groupsError != nil { return groupsError } + result = db.Model(&originalPerson).Update("name", originalPerson.Name) + if result.Error != nil { + err := errors.New("new name already exists") + return err + } + db.Save(&originalPerson) return nil } -func (person Person) Delete(db *gorm.DB) error { - result := db.Delete(&person) +func (person Person) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&person) if result.Error != nil { return result.Error } return nil } -func Create(db *gorm.DB, name string, groups []uint) error { +func Create(db *gorm.DB, params PersonParams) error { + var newGroups []group.Group + log.Println(params) + if len(params.Groups) > 0 { + newGroups = *group.Get(db, params.Groups) + } return Person{ - Name: name, - Groups: *group.Get(db, groups), - }.Create(db) + Name: params.Name, + Groups: newGroups, + }.create(db) } func GetByName(db *gorm.DB, name string) *Person { @@ -65,37 +111,68 @@ func GetByName(db *gorm.DB, name string) *Person { func Get(db *gorm.DB, inputPersons []uint) *[]Person { var outputPersons []Person + if len(inputPersons) < 1 { + db.Model(&Person{}).Select("id").Find(&inputPersons) + } for _, inputPerson := range inputPersons { var outputPerson Person - outputPerson.Get(db, inputPerson) + outputPerson.get(db, inputPerson) outputPersons = append(outputPersons, outputPerson) } return &outputPersons } -func GetAll(db *gorm.DB) *[]Person { - var outputPersonNames []uint - result := db.Model(&Person{}).Select("id").Find(&outputPersonNames) - if result.Error != nil { - log.Println(result.Error) +func Update(db *gorm.DB, params PersonParams) error { + var newGroups []group.Group + if len(params.Groups) > 0 { + newGroups = *group.Get(db, params.Groups) } - return Get(db, outputPersonNames) -} - -func Update(db *gorm.DB, name string, groups []uint) error { return Person{ - Name: name, - Groups: *group.Get(db, groups), - }.Update(db) + Model: gorm.Model{ID: params.IDArray[0]}, + Name: params.Name, + Groups: newGroups, + }.update(db) } func Delete(db *gorm.DB, inputPersons []uint) error { - persons := Get(db, inputPersons) - for _, person := range *persons { - err := person.Delete(db) + var persons []Person + if len(inputPersons) < 1 { + result := db.Model(&Person{}).Select("id").Find(&inputPersons) + if result.Error != nil { + return result.Error + } + } + for _, inputPerson := range inputPersons { + var person Person + person.get(db, inputPerson) + persons = append(persons, person) + } + for _, person := range persons { + err := person.delete(db) if err != nil { return err } } return nil } + +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]Person, error) { + var err error + var params PersonParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]Person + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err +} diff --git a/src/lib/database/role/role.go b/src/lib/database/role/role.go index 09a0f2b..3a8b148 100644 --- a/src/lib/database/role/role.go +++ b/src/lib/database/role/role.go @@ -1,7 +1,8 @@ package role import ( - "log" + "encoding/json" + "errors" group "example.com/database/group" tier "example.com/database/tier" @@ -11,12 +12,40 @@ import ( type Role struct { gorm.Model - Name string `gorm:"primaryKey" json:"name"` + Name string `gorm:"uniqueIndex" json:"name"` Tiers []tier.Tier `gorm:"many2many:role_tier_associations" json:"tiers"` Visibility []group.Group `gorm:"many2many:role_visibility_associations" json:"visibility"` // Unique } -func (role Role) Create(db *gorm.DB) error { +type RoleParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + Name string `json:"name"` + Tiers []uint `json:"tiers"` + Visibility []uint `json:"visibility"` +} + +func (params *RoleParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams RoleParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + if inputParams.Name == "" { + return errors.New("input name cannot be empty") + } + params.Name = inputParams.Name + params.Tiers = inputParams.Tiers + params.Visibility = inputParams.Visibility + return nil +} + +func (role Role) create(db *gorm.DB) error { result := db.Create(&role) if result.Error != nil { return result.Error @@ -27,68 +56,132 @@ func (role Role) Create(db *gorm.DB) error { func (role *Role) getAssociations(db *gorm.DB) { db.Model(&role).Association("Tiers").Find(&role.Tiers) db.Model(&role).Association("Visibility").Find(&role.Visibility) - // } -func (role *Role) Get(db *gorm.DB, inputRole string) { - db.Where("name = ?", inputRole).Take(&role) +func (role *Role) get(db *gorm.DB, inputRole uint) { + db.Where("id = ?", inputRole).Take(&role) role.getAssociations(db) } -func (role Role) Update(db *gorm.DB) error { - result := db.Save(&role) +func (role Role) update(db *gorm.DB) error { + // Get the original Role object + var originalRole Role + result := db.Model(&Role{}).Where("id = ?", role.Model.ID).Take(&originalRole) + if result.Error != nil { + return result.Error + } + // Set the static values + originalRole.Name = role.Name + // Set the associated values by grabbing them from the database + tiersError := db.Model(&originalRole).Association("Tiers").Replace(&role.Tiers) + if tiersError != nil { + return tiersError + } + visibilityError := db.Model(&originalRole).Association("Visibility").Replace(&role.Visibility) + if visibilityError != nil { + return visibilityError + } + result = db.Model(&originalRole).Update("name", originalRole.Name) + if result.Error != nil { + err := errors.New("new name already exists") + return err + } + db.Save(&originalRole) + return nil +} + +func (role Role) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&role) if result.Error != nil { return result.Error } return nil } -func (role Role) Delete(db *gorm.DB) error { - result := db.Delete(&role) - if result.Error != nil { - return result.Error +func Create(db *gorm.DB, params RoleParams) error { + var newTiers []tier.Tier + if len(params.Tiers) > 0 { + newTiers = *tier.Get(db, params.Tiers) + } + var newVisibility []group.Group + if len(params.Visibility) > 0 { + newVisibility = *group.Get(db, params.Visibility) } - return nil -} - -func Create(db *gorm.DB, name string, tiers []uint, visibility []uint) error { return Role{ - Name: name, - Tiers: *tier.Get(db, tiers), - Visibility: *group.Get(db, visibility), - }.Create(db) + Name: params.Name, + Tiers: newTiers, + Visibility: newVisibility, + }.create(db) } -func Get(db *gorm.DB, inputRoles []string) *[]Role { +func Get(db *gorm.DB, inputRoles []uint) *[]Role { var outputRoles []Role + if len(inputRoles) < 1 { + db.Model(&Role{}).Select("id").Find(&inputRoles) + } for _, inputRole := range inputRoles { var outputRole Role - outputRole.Get(db, inputRole) + outputRole.get(db, inputRole) outputRoles = append(outputRoles, outputRole) } return &outputRoles } -func GetAll(db *gorm.DB) *[]Role { - var outputRoleNames []string - result := db.Model(&Role{}).Select("name").Find(&outputRoleNames) - if result.Error != nil { - log.Println(result.Error) +func Update(db *gorm.DB, params RoleParams) error { + var newTiers []tier.Tier + if len(params.Tiers) > 0 { + newTiers = *tier.Get(db, params.Tiers) + } + var newVisibility []group.Group + if len(params.Visibility) > 0 { + newVisibility = *group.Get(db, params.Visibility) } - return Get(db, outputRoleNames) -} - -func Update(db *gorm.DB, name string, tiers []uint, visibility []uint) error { return Role{ - Name: name, - Tiers: *tier.Get(db, tiers), - Visibility: *group.Get(db, visibility), - }.Update(db) + Name: params.Name, + Tiers: newTiers, + Visibility: newVisibility, + }.update(db) } -func Delete(db *gorm.DB, inputRoles []string) { - roles := Get(db, inputRoles) - for _, role := range *roles { - role.Delete(db) +func Delete(db *gorm.DB, inputRoles []uint) error { + var roles []Role + if len(inputRoles) < 1 { + result := db.Model(&Role{}).Select("id").Find(&inputRoles) + if result.Error != nil { + return result.Error + } } + for _, inputRole := range inputRoles { + var function Role + function.get(db, inputRole) + roles = append(roles, function) + } + for _, role := range roles { + err := role.delete(db) + if err != nil { + return err + } + } + return nil +} + +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]Role, error) { + var err error + var params RoleParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]Role + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err } diff --git a/src/lib/database/schematic/schematic.go b/src/lib/database/schematic/schematic.go index 9c308fc..e6a4d28 100644 --- a/src/lib/database/schematic/schematic.go +++ b/src/lib/database/schematic/schematic.go @@ -1,7 +1,7 @@ package schematic import ( - "log" + "encoding/json" function "example.com/database/function" group "example.com/database/group" @@ -20,7 +20,38 @@ type Schematic struct { Visibility []group.Group `gorm:"many2many:schematic_group_associations" json:"visibility"` // Unique } -func (schematic Schematic) Create(db *gorm.DB) error { +type SchematicParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + Material []uint `json:"material"` + Tools []uint `json:"tools"` + Requirements []uint `json:"requirements"` + TimeUnits int64 `json:"time_units"` + Result uint `json:"result"` + Visibility []uint `json:"visibility"` +} + +func (params *SchematicParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams SchematicParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + params.Material = inputParams.Material + params.Tools = inputParams.Tools + params.Requirements = inputParams.Requirements + params.TimeUnits = inputParams.TimeUnits + params.Result = inputParams.Result + params.Visibility = inputParams.Visibility + return nil +} + +func (schematic Schematic) create(db *gorm.DB) error { result := db.Create(&schematic) if result.Error != nil { return result.Error @@ -36,12 +67,21 @@ func (schematic *Schematic) getAssociations(db *gorm.DB) { db.Model(&schematic).Association("Visibility").Find(&schematic.Visibility) } -func (schematic *Schematic) Get(db *gorm.DB, inputSchematic uint) { +func (schematic *Schematic) get(db *gorm.DB, inputSchematic uint) { db.Model(&Schematic{}).Where("id = ?", inputSchematic).Take(&schematic) schematic.getAssociations(db) } -func (schematic Schematic) Update(db *gorm.DB) error { +func (schematic Schematic) update(db *gorm.DB) error { + // Get the original Schematic object + var originalSchematic Schematic + result := db.Model(&Schematic{}).Where("id = ?", schematic.Model.ID).Take(&originalSchematic) + if result.Error != nil { + return result.Error + } + // Set the static values + originalSchematic.TimeUnits = schematic.TimeUnits + // Set the associated values by grabbing them from the database materialError := db.Model(&schematic).Association("Material").Replace(&schematic.Material) if materialError != nil { return materialError @@ -62,61 +102,128 @@ func (schematic Schematic) Update(db *gorm.DB) error { if visibilityError != nil { return visibilityError } + db.Save(&originalSchematic) return nil } -func (schematic Schematic) Delete(db *gorm.DB) error { - result := db.Delete(&schematic) +func (schematic Schematic) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&schematic) if result.Error != nil { return result.Error } return nil } -func Create(db *gorm.DB, material []uint, tools []uint, requirements []uint, timeUnits int64, result uint, visibility []uint) error { +func Create(db *gorm.DB, params SchematicParams) error { + var newMaterial []inventoryslot.InventorySlot + if len(params.Material) > 0 { + newMaterial = *inventoryslot.Get(db, params.Material) + } + var newTools []inventoryslot.InventorySlot + if len(params.Tools) > 0 { + newTools = *inventoryslot.Get(db, params.Tools) + } + var newRequirements []function.Function + if len(params.Requirements) > 0 { + newRequirements = *function.Get(db, params.Requirements) + } + resultArray := *inventoryslot.Get(db, []uint{params.Result}) + newResult := resultArray[0] + var newVisibility []group.Group + if len(params.Visibility) > 0 { + newVisibility = *group.Get(db, params.Visibility) + } return Schematic{ - Material: *inventoryslot.Get(db, material), - Tools: *inventoryslot.Get(db, tools), - Requirements: *function.Get(db, requirements), - TimeUnits: timeUnits, - Result: (*inventoryslot.Get(db, []uint{result}))[0], - Visibility: *group.Get(db, visibility), - }.Create(db) + Material: newMaterial, + Tools: newTools, + Requirements: newRequirements, + TimeUnits: params.TimeUnits, + Result: newResult, + Visibility: newVisibility, + }.create(db) } func Get(db *gorm.DB, inputSchematics []uint) *[]Schematic { var outputSchematics []Schematic + if len(inputSchematics) < 1 { + db.Model(&Schematic{}).Select("id").Find(&inputSchematics) + } for _, inputSchematic := range inputSchematics { var outputSchematic Schematic - outputSchematic.Get(db, inputSchematic) + outputSchematic.get(db, inputSchematic) outputSchematics = append(outputSchematics, outputSchematic) } return &outputSchematics } -func GetAll(db *gorm.DB) *[]Schematic { - var outputSchematics []uint - result := db.Model(&Schematic{}).Select("id").Find(&outputSchematics) - if result.Error != nil { - log.Println(result.Error) +func Update(db *gorm.DB, params SchematicParams) error { + var newMaterial []inventoryslot.InventorySlot + if len(params.Material) > 0 { + newMaterial = *inventoryslot.Get(db, params.Material) + } + var newTools []inventoryslot.InventorySlot + if len(params.Tools) > 0 { + newTools = *inventoryslot.Get(db, params.Tools) + } + var newRequirements []function.Function + if len(params.Requirements) > 0 { + newRequirements = *function.Get(db, params.Requirements) + } + resultArray := *inventoryslot.Get(db, []uint{params.Result}) + newResult := resultArray[0] + var newVisibility []group.Group + if len(params.Visibility) > 0 { + newVisibility = *group.Get(db, params.Visibility) } - return Get(db, outputSchematics) -} - -func Update(db *gorm.DB, material []uint, tools []uint, requirements []uint, timeUnits int64, result uint, visibility []uint) error { return Schematic{ - Material: *inventoryslot.Get(db, material), - Tools: *inventoryslot.Get(db, tools), - Requirements: *function.Get(db, requirements), - TimeUnits: timeUnits, - Result: (*inventoryslot.Get(db, []uint{result}))[0], - Visibility: *group.Get(db, visibility), - }.Update(db) + Material: newMaterial, + Tools: newTools, + Requirements: newRequirements, + TimeUnits: params.TimeUnits, + Result: newResult, + Visibility: newVisibility, + }.update(db) } -func Delete(db *gorm.DB, inputSchematics []uint) { - schematics := Get(db, inputSchematics) - for _, schematic := range *schematics { - schematic.Delete(db) +func Delete(db *gorm.DB, inputSchematics []uint) error { + var schematics []Schematic + // if len(inputSchematics) < 1 { + // result := db.Model(&Schematic{}).Select("id").Find(&inputSchematics) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputSchematic := range inputSchematics { + var schematic Schematic + schematic.get(db, inputSchematic) + schematics = append(schematics, schematic) } + for _, schematic := range schematics { + err := schematic.delete(db) + if err != nil { + return err + } + } + return nil +} + +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]Schematic, error) { + var err error + var params SchematicParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err + } + var result *[]Schematic + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err } diff --git a/src/lib/database/tier/tier.go b/src/lib/database/tier/tier.go index f433ef4..6d2131c 100644 --- a/src/lib/database/tier/tier.go +++ b/src/lib/database/tier/tier.go @@ -1,7 +1,7 @@ package tier import ( - "log" + "encoding/json" functionset "example.com/database/functionset" @@ -13,7 +13,28 @@ type Tier struct { FunctionSets []functionset.FunctionSet `gorm:"many2many:tier_functionset_associations" json:"function_sets"` } -func (tier Tier) Create(db *gorm.DB) error { +type TierParams struct { + // ID(s) of the object being modified + IDArray []uint `json:"id"` + // New fields + FunctionSets []uint `json:"function_sets"` +} + +func (params *TierParams) parse(IDUintArray *[]uint, body *[]byte) error { + var inputParams TierParams + params.IDArray = *IDUintArray + if len(*body) == 0 { + return nil + } + err := json.Unmarshal(*body, &inputParams) + if err != nil { + return err + } + params.FunctionSets = inputParams.FunctionSets + return nil +} + +func (tier Tier) create(db *gorm.DB) error { result := db.Create(&tier) if result.Error != nil { return result.Error @@ -25,63 +46,108 @@ func (tier *Tier) getAssociations(db *gorm.DB) { db.Model(&tier).Association("FunctionSets").Find(&tier.FunctionSets) } -func (tier *Tier) Get(db *gorm.DB, inputTier uint) { +func (tier *Tier) get(db *gorm.DB, inputTier uint) { db.Where("id = ?", inputTier).Take(&tier) tier.getAssociations(db) } -func (tier Tier) Update(db *gorm.DB) error { - result := db.Save(&tier) +func (tier Tier) update(db *gorm.DB) error { + // Get the original Tier object + var originalTier Tier + result := db.Model(&Tier{}).Where("id = ?", tier.Model.ID).Take(&originalTier) + if result.Error != nil { + return result.Error + } + // Set the associated values by grabbing them from the database + tagsError := db.Model(&originalTier).Association("FunctionSets").Replace(&tier.FunctionSets) + if tagsError != nil { + return tagsError + } + db.Save(&originalTier) + return nil +} + +func (tier Tier) delete(db *gorm.DB) error { + result := db.Unscoped().Delete(&tier) if result.Error != nil { return result.Error } return nil } -func (tier Tier) Delete(db *gorm.DB) error { - result := db.Delete(&tier) - if result.Error != nil { - return result.Error +func Create(db *gorm.DB, params TierParams) error { + var newFunctionSets []functionset.FunctionSet + if len(params.FunctionSets) > 0 { + newFunctionSets = *functionset.Get(db, params.FunctionSets) } - return nil -} - -func Create(db *gorm.DB, functionSets []uint) error { return Tier{ - FunctionSets: *functionset.Get(db, functionSets), - }.Create(db) + FunctionSets: newFunctionSets, + }.create(db) } func Get(db *gorm.DB, inputTiers []uint) *[]Tier { var outputTiers []Tier + if len(inputTiers) < 1 { + db.Model(&Tier{}).Select("id").Find(&inputTiers) + } for _, inputTier := range inputTiers { var outputTier Tier - outputTier.Get(db, inputTier) + outputTier.get(db, inputTier) outputTiers = append(outputTiers, outputTier) } return &outputTiers } -func GetAll(db *gorm.DB) *[]Tier { - var outputTierIDs []uint - result := db.Find(&outputTierIDs) - if result.Error != nil { - log.Println(result.Error) +func Update(db *gorm.DB, params TierParams) error { + var newFunctionSets []functionset.FunctionSet + if len(params.FunctionSets) > 0 { + newFunctionSets = *functionset.Get(db, params.FunctionSets) } - return Get(db, outputTierIDs) + return Tier{ + Model: gorm.Model{ID: params.IDArray[0]}, + FunctionSets: newFunctionSets, + }.update(db) } -func Update(db *gorm.DB, id int, functionSets []uint) error { - outputTier := Tier{ - FunctionSets: *functionset.Get(db, functionSets), +func Delete(db *gorm.DB, inputTiers []uint) error { + var tiers []Tier + // if len(inputTiers) < 1 { + // result := db.Model(&Tier{}).Select("id").Find(&inputTiers) + // if result.Error != nil { + // return result.Error + // } + // } + for _, inputTier := range inputTiers { + var tier Tier + tier.get(db, inputTier) + tiers = append(tiers, tier) } - outputTier.ID = uint(id) - return outputTier.Update(db) + for _, tier := range tiers { + err := tier.delete(db) + if err != nil { + return err + } + } + return nil } -func Delete(db *gorm.DB, inputTiers []uint) { - tiers := Get(db, inputTiers) - for _, tier := range *tiers { - tier.Delete(db) +func HandleRequest(method string, db *gorm.DB, IDUintArray *[]uint, body *[]byte) (*[]Tier, error) { + var err error + var params TierParams + err = params.parse(IDUintArray, body) + if err != nil { + return nil, err } + var result *[]Tier + switch method { + case "GET": + result = Get(db, params.IDArray) + case "POST": + err = Create(db, params) + case "PUT": + err = Update(db, params) + case "DELETE": + err = Delete(db, params.IDArray) + } + return result, err } diff --git a/src/lib/database/user/user.go b/src/lib/database/user/user.go index dfb30d2..86ea605 100644 --- a/src/lib/database/user/user.go +++ b/src/lib/database/user/user.go @@ -103,7 +103,7 @@ func (user User) Update(db *gorm.DB) error { } func (user User) Delete(db *gorm.DB) error { - result := db.Delete(&user) + result := db.Unscoped().Delete(&user) if result.Error != nil { return result.Error } @@ -146,7 +146,7 @@ func Exists(db *gorm.DB, id string) bool { } func Create(db *gorm.DB, discordId string, displayName string, username string, avatar string, avatarDecoration string, loginToken string, loggedIn bool) error { - person.Create(db, displayName, []uint{}) + person.Create(db, person.PersonParams{Name: displayName, Groups: []uint{}}) newPerson := person.GetByName(db, username) newUser := User{ Id: discordId,