From 07572621430a2b44a6377c21f51e9bdd0aaba6f1 Mon Sep 17 00:00:00 2001 From: Jeffrey Duroyon Date: Tue, 24 Aug 2021 00:11:00 +0200 Subject: [PATCH] clean up --- handlers_v2/cage_handler.go | 69 +++++ handlers_v2/hamster_handler.go | 207 ++++++++++++++ handlers_v2/handler.go | 126 ++++++++ handlers_v2/health_handler.go | 12 + handlers_v2/user_handler.go | 268 ++++++++++++++++++ .../changelogs/changeset/add-game-name.xml | 11 - .../changelogs/changeset/create-cage.xml | 2 +- .../changelogs/changeset/create-game.xml | 22 -- .../changelogs/changeset/create-hamster.xml | 3 + service/game_service.go | 30 -- storage/dao/database.go | 17 +- storage/dao/fake/database_fake.go | 37 --- storage/dao/fake/database_fake_cages.go | 73 ----- storage/dao/fake/database_fake_games.go | 77 ----- storage/dao/fake/database_fake_hamsters.go | 73 ----- storage/dao/fake/database_fake_users.go | 106 ------- .../postgresql/database_postgresql_cages.go | 48 +--- .../postgresql/database_postgresql_games.go | 127 --------- .../database_postgresql_hamsters.go | 25 +- storage/model/cage.go | 1 - storage/model/game.go | 13 - storage/model/user.go | 1 - 22 files changed, 716 insertions(+), 632 deletions(-) create mode 100644 handlers_v2/cage_handler.go create mode 100644 handlers_v2/hamster_handler.go create mode 100755 handlers_v2/handler.go create mode 100755 handlers_v2/health_handler.go create mode 100755 handlers_v2/user_handler.go delete mode 100644 liquibase/changelogs/changeset/add-game-name.xml delete mode 100644 liquibase/changelogs/changeset/create-game.xml delete mode 100644 service/game_service.go delete mode 100755 storage/dao/fake/database_fake.go delete mode 100755 storage/dao/fake/database_fake_cages.go delete mode 100755 storage/dao/fake/database_fake_games.go delete mode 100755 storage/dao/fake/database_fake_hamsters.go delete mode 100755 storage/dao/fake/database_fake_users.go delete mode 100755 storage/dao/postgresql/database_postgresql_games.go delete mode 100644 storage/model/game.go diff --git a/handlers_v2/cage_handler.go b/handlers_v2/cage_handler.go new file mode 100644 index 0000000..2d00f9a --- /dev/null +++ b/handlers_v2/cage_handler.go @@ -0,0 +1,69 @@ +package handlers + +import ( + "hamster-tycoon/storage/dao" + "hamster-tycoon/storage/model" + "hamster-tycoon/storage/validators" + "hamster-tycoon/utils" + "net/http" + + "github.com/gin-gonic/gin" +) + +func (hc *handlersContext) getAllCages(c *gin.Context) { + gameID := c.Param("gameID") + err := hc.validator.VarCtx(c, gameID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + cages, err := hc.db.GetAllCages(gameID) + if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while getting cages") + utils.JSONErrorWithMessage(c.Writer, model.ErrInternalServer, "Error while getting cages") + return + } + utils.JSON(c.Writer, http.StatusOK, cages) +} + +func (hc *handlersContext) getACage(c *gin.Context) { + cageID := c.Param("cageID") + gameID := c.Param("gameID") + + err := hc.validator.VarCtx(c, cageID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + err = hc.validator.VarCtx(c, gameID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + cage, err := hc.db.GetCageByID(gameID, cageID) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeNotFound: + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Cage not found") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error GetCage: get cage error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while get cage") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + if cage == nil { + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Cage not found") + return + } + + utils.JSON(c.Writer, http.StatusOK, cage) +} diff --git a/handlers_v2/hamster_handler.go b/handlers_v2/hamster_handler.go new file mode 100644 index 0000000..89ba0db --- /dev/null +++ b/handlers_v2/hamster_handler.go @@ -0,0 +1,207 @@ +package handlers + +import ( + "encoding/json" + "github.com/gin-gonic/gin" + "hamster-tycoon/storage/dao" + "hamster-tycoon/storage/model" + "hamster-tycoon/storage/validators" + "hamster-tycoon/utils" + "net/http" +) + +func (hc *handlersContext) getAllHamsters(c *gin.Context) { + gameID := c.Param("gameID") + cageID := c.Param("cageID") + + err := hc.validator.VarCtx(c, cageID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + err = hc.validator.VarCtx(c, gameID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + hamsters, err := hc.db.GetAllHamsters(gameID, cageID) + if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while getting hamsters") + utils.JSONErrorWithMessage(c.Writer, model.ErrInternalServer, "Error while getting hamsters") + return + } + utils.JSON(c.Writer, http.StatusOK, hamsters) +} + +func (hc *handlersContext) getAHamster(c *gin.Context) { + gameID := c.Param("gameID") + cageID := c.Param("cageID") + hamsterID := c.Param("hamsterID") + + err := hc.validator.VarCtx(c, cageID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + err = hc.validator.VarCtx(c, gameID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + err = hc.validator.VarCtx(c, hamsterID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + hamster, err := hc.db.GetHamsterByID(hamsterID, gameID, cageID) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeNotFound: + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Hamster not found") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error GetHamster: get hamster error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while get hamster") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + if hamster == nil { + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Hamster not found") + return + } + + utils.JSON(c.Writer, http.StatusOK, hamster) +} + +func (hc *handlersContext) createAHamster(c *gin.Context) { + gameID := c.Param("gameID") + cageID := c.Param("cageID") + + err := hc.validator.VarCtx(c, cageID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + err = hc.validator.VarCtx(c, gameID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + b, err := c.GetRawData() + if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while creating hamster, read data fail") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + hamsterToCreate := model.Hamster{} + err = json.Unmarshal(b, &hamsterToCreate) + if err != nil { + utils.JSONError(c.Writer, model.ErrBadRequestFormat) + return + } + + err = hc.validator.StructCtx(c, hamsterToCreate) + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + hamsterToCreate.Cage = &model.Cage{ID: cageID, Game: model.Game{ID: gameID}} + err = hc.db.CreateHamster(&hamsterToCreate) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeDuplicate: + utils.JSONErrorWithMessage(c.Writer, model.ErrAlreadyExists, "Hamster already exists") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error CreateHamster: Error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while creating hamster") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + utils.JSON(c.Writer, http.StatusCreated, hamsterToCreate) +} + +func (hc *handlersContext) updateAHamster(c *gin.Context) { + panic("TO DO") +} + +func (hc *handlersContext) deleteAHamster(c *gin.Context) { + hamsterID := c.Param("hamsterID") + gameID := c.Param("gameID") + cageID := c.Param("cageID") + + err := hc.validator.VarCtx(c, cageID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + err = hc.validator.VarCtx(c, gameID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + err = hc.validator.VarCtx(c, hamsterID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + // check hamster id given in URL exists + _, err = hc.db.GetHamsterByID(hamsterID, gameID, cageID) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeNotFound: + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Hamster to delete not found") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error DeleteHamster: get hamster error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while get hamster to delete") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + err = hc.db.DeleteHamster(hamsterID) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeNotFound: + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "Hamster to delete not found") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error DeleteHamster: Error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while deleting hamster") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + utils.JSON(c.Writer, http.StatusNoContent, nil) + +} diff --git a/handlers_v2/handler.go b/handlers_v2/handler.go new file mode 100755 index 0000000..6d9749e --- /dev/null +++ b/handlers_v2/handler.go @@ -0,0 +1,126 @@ +package handlers + +import ( + "hamster-tycoon/middlewares" + "hamster-tycoon/service" + "hamster-tycoon/storage/dao" + "hamster-tycoon/storage/dao/fake" + "hamster-tycoon/storage/dao/postgresql" + "hamster-tycoon/storage/validators" + "net/http" + "time" + + "reflect" + "strings" + + "github.com/gin-contrib/cors" + "github.com/gin-gonic/gin" + "gopkg.in/go-playground/validator.v9" +) + +type Config struct { + Mock bool + DBConnectionURI string + Port int + LogLevel string + LogFormat string +} + +type handlersContext struct { + db dao.Database + validator *validator.Validate + userService *service.UserService + gameService *service.GameService + cageService *service.CageService + hamsterService *service.HamsterService +} + +func NewRouter(config *Config) *gin.Engine { + gin.SetMode(gin.ReleaseMode) + + router := gin.New() + router.HandleMethodNotAllowed = true + + router.Use(cors.New(cors.Config{ + AllowOrigins: []string{"*"}, + AllowMethods: []string{"*"}, + AllowHeaders: []string{"*"}, + ExposeHeaders: []string{"*"}, + AllowCredentials: true, + MaxAge: 12 * time.Hour, + })) + router.Use(gin.Recovery()) + router.Use(middlewares.GetLoggerMiddleware()) + router.Use(middlewares.GetHTTPLoggerMiddleware()) + + hc := &handlersContext{} + if config.Mock { + hc.db = fake.NewDatabaseFake() + } else { + hc.db = postgresql.NewDatabasePostgreSQL(config.DBConnectionURI) + } + hc.validator = newValidator() + hc.userService = service.NewUserService(hc.db) + hc.gameService = service.NewGameService(hc.db) + hc.cageService = service.NewCageService(hc.db) + hc.hamsterService = service.NewHamsterService(hc.db) + + public := router.Group("/") + public.Handle(http.MethodGet, "/_health", hc.GetHealth) + + userRoute := public.Group("/users") + userRoute.Handle("LOGIN", "", hc.connectUser) + userRoute.Handle(http.MethodPost, "", hc.createUser) + + securedUserRoute := userRoute.Group("") + //TODO add secure auth + securedUserRoute.Handle(http.MethodGet, "", hc.getAllUsers) + securedUserRoute.Handle(http.MethodGet, "/:userID", hc.getUser) + securedUserRoute.Handle(http.MethodPut, "/:userID", hc.updateUser) + securedUserRoute.Handle(http.MethodDelete, "/:userID", hc.deleteUser) + // end: user routes + + gameRoute := securedUserRoute.Group("/:userID/games") + gameRoute.Handle(http.MethodGet, "", hc.getAllGames) + gameRoute.Handle(http.MethodGet, "/:gameID", hc.getAGame) + gameRoute.Handle(http.MethodPost, "/:gameID", hc.createAGame) + gameRoute.Handle(http.MethodPut, "/:gameID", hc.updateAGame) + gameRoute.Handle(http.MethodGet, "/:gameID/hamsters", hc.getHamstersOfGame) + gameRoute.Handle(http.MethodDelete, "/:gameID", hc.deleteAGame) + + cageRoute := gameRoute.Group("/:gameID/cages") + cageRoute.Handle(http.MethodGet, "", hc.getAllCages) + cageRoute.Handle(http.MethodGet, "/:cageID", hc.getACage) + cageRoute.Handle(http.MethodPost, "/:cageID", hc.createACage) + cageRoute.Handle(http.MethodPut, "/:cageID", hc.updateACage) + cageRoute.Handle(http.MethodDelete, "/:cageID", hc.deleteACage) + + hamsterRoute := cageRoute.Group("/:cageID/hamsters") + hamsterRoute.Handle(http.MethodGet, "", hc.getAllHamsters) + hamsterRoute.Handle(http.MethodGet, "/:hamsterID", hc.getAHamster) + hamsterRoute.Handle(http.MethodPost, "/:hamsterID", hc.createAHamster) + hamsterRoute.Handle(http.MethodPut, "/:hamsterID", hc.updateAHamster) + hamsterRoute.Handle(http.MethodDelete, "/:hamsterID", hc.deleteAHamster) + + return router +} + +func newValidator() *validator.Validate { + va := validator.New() + + va.RegisterTagNameFunc(func(fld reflect.StructField) string { + name := strings.SplitN(fld.Tag.Get("json"), ",", 2) + if len(name) < 1 { + return "" + } + return name[0] + }) + + for k, v := range validators.CustomValidators { + if v.Validator != nil { + va.RegisterValidationCtx(k, v.Validator) + } + } + + return va +} diff --git a/handlers_v2/health_handler.go b/handlers_v2/health_handler.go new file mode 100755 index 0000000..1a2cb76 --- /dev/null +++ b/handlers_v2/health_handler.go @@ -0,0 +1,12 @@ +package handlers + +import ( + "hamster-tycoon/utils" + "net/http" + + "github.com/gin-gonic/gin" +) + +func (hc *handlersContext) GetHealth(c *gin.Context) { + utils.JSON(c.Writer, http.StatusNoContent, nil) +} diff --git a/handlers_v2/user_handler.go b/handlers_v2/user_handler.go new file mode 100755 index 0000000..317deea --- /dev/null +++ b/handlers_v2/user_handler.go @@ -0,0 +1,268 @@ +package handlers + +import ( + "encoding/json" + "fmt" + "hamster-tycoon/storage/dao" + "hamster-tycoon/storage/model" + "hamster-tycoon/storage/validators" + "hamster-tycoon/utils" + "net/http" + "strings" + + "github.com/gin-gonic/gin" + "google.golang.org/api/oauth2/v2" +) + +func (hc *handlersContext) getAllUsers(c *gin.Context) { + users, err := hc.db.GetAllUsers() + if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while getting users") + utils.JSONErrorWithMessage(c.Writer, model.ErrInternalServer, "Error while getting users") + return + } + utils.JSON(c.Writer, http.StatusOK, users) +} + +func (hc *handlersContext) connectUser(c *gin.Context) { + authorizationHeader := c.GetHeader("Authorization") + authorizationHeaderSplitted := strings.Split(authorizationHeader, " ") + if len(authorizationHeaderSplitted) != 2 { + utils.JSONError(c.Writer, model.ErrBadRequestFormat) + return + } + + oauth2Service, err := oauth2.New(&http.Client{}) + if oauth2Service == nil { + fmt.Println(err) + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + tokenInfoCall := oauth2Service.Tokeninfo() + tokenInfoCall.IdToken(authorizationHeaderSplitted[1]) + tokenInfo, err := tokenInfoCall.Do() + if err != nil { + utils.GetLogger().WithError(err).Error(err) + utils.JSONError(c.Writer, model.ErrBadRequestFormat) + return + } + user, err := hc.userService.GetUserFromGoogleID(tokenInfo.UserId) + if err != nil { + utils.GetLogger().WithError(err).Error(err) + if castedError, ok := err.(*model.APIError); ok { + if castedError.Type == model.ErrNotFound.Type { + user, err := hc.userService.CreateUserFromGoogleToken(tokenInfo.UserId, tokenInfo.Email) + if err != nil { + fmt.Println(err) + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + utils.JSON(c.Writer, 200, user) + return + } + utils.JSONError(c.Writer, *castedError) + return + } + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + fmt.Println("Found the user " + user.Nickname) + fmt.Println("Return 200") + utils.JSON(c.Writer, 200, user) +} +func (hc *handlersContext) createUser(c *gin.Context) { + b, err := c.GetRawData() + if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while creating user, read data fail") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + userToCreate := model.UserEditable{} + err = json.Unmarshal(b, &userToCreate) + if err != nil { + utils.JSONError(c.Writer, model.ErrBadRequestFormat) + return + } + + err = hc.validator.StructCtx(c, userToCreate) + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + user := model.User{ + UserEditable: userToCreate, + } + + err = hc.db.CreateUser(&user) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeDuplicate: + utils.JSONErrorWithMessage(c.Writer, model.ErrAlreadyExists, "User already exists") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error CreateUser: Error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while creating user") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + utils.JSON(c.Writer, http.StatusCreated, user) +} + +func (hc *handlersContext) getUser(c *gin.Context) { + userID := c.Param("id") + + err := hc.validator.VarCtx(c, userID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + user, err := hc.db.GetUsersByID(userID) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeNotFound: + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User not found") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error GetUser: get user error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while get user") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + if user == nil { + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User not found") + return + } + + utils.JSON(c.Writer, http.StatusOK, user) +} + +func (hc *handlersContext) deleteUser(c *gin.Context) { + userID := c.Param("id") + + err := hc.validator.VarCtx(c, userID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + // check user id given in URL exists + _, err = hc.db.GetUsersByID(userID) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeNotFound: + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User to delete not found") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error DeleteUser: get user error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while get user to delete") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + err = hc.db.DeleteUser(userID) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeNotFound: + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User to delete not found") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error DeleteUser: Error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while deleting user") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + utils.JSON(c.Writer, http.StatusNoContent, nil) +} + +func (hc *handlersContext) updateUser(c *gin.Context) { + userID := c.Param("id") + + err := hc.validator.VarCtx(c, userID, "uuid4") + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + // check user id given in URL exists + user, err := hc.db.GetUsersByID(userID) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeNotFound: + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User to update not found") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("deleteUser: get user error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while get user to update") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + // get body and verify data + b, err := c.GetRawData() + if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while updating user, read data fail") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + userToUpdate := model.UserEditable{} + err = json.Unmarshal(b, &userToUpdate) + if err != nil { + utils.JSONError(c.Writer, model.ErrBadRequestFormat) + return + } + + err = hc.validator.StructCtx(c, userToUpdate) + if err != nil { + utils.JSONError(c.Writer, validators.NewDataValidationAPIError(err)) + return + } + + user.UserEditable = userToUpdate + + // make the update + err = hc.db.UpdateUser(user) + if e, ok := err.(*dao.Error); ok { + switch { + case e.Type == dao.ErrTypeNotFound: + utils.JSONErrorWithMessage(c.Writer, model.ErrNotFound, "User to update not found") + return + default: + utils.GetLoggerFromCtx(c).WithError(err).WithField("type", e.Type).Error("error UpdateUser: Error type not handled") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + } else if err != nil { + utils.GetLoggerFromCtx(c).WithError(err).Error("error while deleting user") + utils.JSONError(c.Writer, model.ErrInternalServer) + return + } + + utils.JSON(c.Writer, http.StatusOK, user) +} diff --git a/liquibase/changelogs/changeset/add-game-name.xml b/liquibase/changelogs/changeset/add-game-name.xml deleted file mode 100644 index b0a12b1..0000000 --- a/liquibase/changelogs/changeset/add-game-name.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/liquibase/changelogs/changeset/create-cage.xml b/liquibase/changelogs/changeset/create-cage.xml index a43c641..5f1e297 100644 --- a/liquibase/changelogs/changeset/create-cage.xml +++ b/liquibase/changelogs/changeset/create-cage.xml @@ -14,7 +14,7 @@ - + diff --git a/liquibase/changelogs/changeset/create-game.xml b/liquibase/changelogs/changeset/create-game.xml deleted file mode 100644 index bfa1aa0..0000000 --- a/liquibase/changelogs/changeset/create-game.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/liquibase/changelogs/changeset/create-hamster.xml b/liquibase/changelogs/changeset/create-hamster.xml index 77d6c90..5e6ee0d 100644 --- a/liquibase/changelogs/changeset/create-hamster.xml +++ b/liquibase/changelogs/changeset/create-hamster.xml @@ -53,6 +53,9 @@ + + + diff --git a/service/game_service.go b/service/game_service.go deleted file mode 100644 index 58ca55b..0000000 --- a/service/game_service.go +++ /dev/null @@ -1,30 +0,0 @@ -package service - -import ( - "hamster-tycoon/storage/dao" - "hamster-tycoon/storage/model" -) - -type GameService struct { - serviceContext -} - -func NewGameService(database dao.Database) *GameService { - return &GameService{serviceContext{db: database}} -} - -func (gs *GameService) GetAGameByID(id string) (*model.Game, error) { - game, err := gs.db.GetGameByID(id) - if err != nil { - if castedError, ok := err.(*dao.Error); ok { - switch castedError.Type { - case dao.ErrTypeNotFound: - return nil, &model.ErrNotFound - default: - return nil, &model.ErrInternalServer - } - } - return nil, &model.ErrInternalServer - } - return game, nil -} diff --git a/storage/dao/database.go b/storage/dao/database.go index b3b1cc4..f5beddb 100755 --- a/storage/dao/database.go +++ b/storage/dao/database.go @@ -15,28 +15,19 @@ type Database interface { UpdateUser(*model.User) error // end: user dao funcs - // start: cage games funcs - GetAllGames() ([]*model.Game, error) - GetGameByID(string) (*model.Game, error) - CreateGame(*model.Game) error - DeleteGame(string) error - UpdateGame(*model.Game) error - // end: games dao funcs - // start: cage funcs - GetAllCages(string) ([]*model.Cage, error) - GetCageByID(string, string) (*model.Cage, error) + GetAllCages() ([]*model.Cage, error) + GetCageByID(string) (*model.Cage, error) CreateCage(*model.Cage) error DeleteCage(string) error UpdateCage(*model.Cage) error // end: cage dao funcs // start: hamster funcs - GetAllHamsters(string, string) ([]*model.Hamster, error) - GetHamsterByID(string, string, string) (*model.Hamster, error) + GetAllHamsters(string) ([]*model.Hamster, error) + GetHamsterByID(string, string) (*model.Hamster, error) CreateHamster(*model.Hamster) error DeleteHamster(string) error UpdateHamster(*model.Hamster) error - GetHamstersOfGame(string) ([]*model.Hamster, error) // end: hamster dao funcs } diff --git a/storage/dao/fake/database_fake.go b/storage/dao/fake/database_fake.go deleted file mode 100755 index 262ed95..0000000 --- a/storage/dao/fake/database_fake.go +++ /dev/null @@ -1,37 +0,0 @@ -package fake - -import ( - "encoding/json" - "hamster-tycoon/storage/dao" - "hamster-tycoon/utils" - "time" - - "github.com/allegro/bigcache" -) - -type DatabaseFake struct { - Cache *bigcache.BigCache -} - -func NewDatabaseFake() dao.Database { - cache, err := bigcache.NewBigCache(bigcache.DefaultConfig(time.Minute)) - if err != nil { - utils.GetLogger().WithError(err).Fatal("Error while instantiate cache") - } - return &DatabaseFake{ - Cache: cache, - } -} - -func (db *DatabaseFake) save(key string, data []interface{}) { - b, err := json.Marshal(data) - if err != nil { - utils.GetLogger().WithError(err).Errorf("Error while marshal fake %s", key) - db.Cache.Set(key, []byte("[]")) - return - } - err = db.Cache.Set(key, b) - if err != nil { - utils.GetLogger().WithError(err).Errorf("Error while saving fake %s", key) - } -} diff --git a/storage/dao/fake/database_fake_cages.go b/storage/dao/fake/database_fake_cages.go deleted file mode 100755 index 1f8d853..0000000 --- a/storage/dao/fake/database_fake_cages.go +++ /dev/null @@ -1,73 +0,0 @@ -package fake - -import ( - "encoding/json" - "errors" - uuid "github.com/satori/go.uuid" - "hamster-tycoon/storage/dao" - "hamster-tycoon/storage/model" - "hamster-tycoon/utils" -) - -const ( - cacheKeyCages = "cages" -) - -func (db *DatabaseFake) saveCages(cages []*model.Cage) { - data := make([]interface{}, 0) - for _, v := range cages { - data = append(data, v) - } - db.save(cacheKeyCages, data) -} - -func (db *DatabaseFake) loadCages() []*model.Cage { - cages := make([]*model.Cage, 0) - b, err := db.Cache.Get(cacheKeyCages) - if err != nil { - return cages - } - err = json.Unmarshal(b, &cages) - if err != nil { - utils.GetLogger().WithError(err).Error("Error while unmarshal fake users") - } - return cages -} - -func (db *DatabaseFake) GetAllCages(gameID string) ([]*model.Cage, error) { - cages := db.loadCages() - var cagesLoaded []*model.Cage - for _, g := range cages { - if g.Game.ID == gameID { - cagesLoaded = append(cagesLoaded, g) - } - } - return cagesLoaded, nil -} - -func (db *DatabaseFake) GetCageByID(gameID, cageID string) (*model.Cage, error) { - cages := db.loadCages() - for _, g := range cages { - if g.Game.ID == gameID && g.ID == cageID { - return g, nil - } - } - return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("cage not found")) -} - -func (db *DatabaseFake) CreateCage(cage *model.Cage) error { - cage.ID = uuid.NewV4().String() - - cages := db.loadCages() - cages = append(cages, cage) - db.saveCages(cages) - return nil -} - -func (db *DatabaseFake) DeleteCage(string) error { - return nil -} - -func (db *DatabaseFake) UpdateCage(*model.Cage) error { - return nil -} diff --git a/storage/dao/fake/database_fake_games.go b/storage/dao/fake/database_fake_games.go deleted file mode 100755 index 5525195..0000000 --- a/storage/dao/fake/database_fake_games.go +++ /dev/null @@ -1,77 +0,0 @@ -package fake - -import ( - "encoding/json" - "errors" - uuid "github.com/satori/go.uuid" - "hamster-tycoon/storage/dao" - "hamster-tycoon/storage/model" - "hamster-tycoon/utils" -) - -const ( - cacheKeyGames = "games" -) - -func (db *DatabaseFake) saveGames(games []*model.Game) { - data := make([]interface{}, 0) - for _, v := range games { - data = append(data, v) - } - db.save(cacheKeyGames, data) -} - -func (db *DatabaseFake) loadGames() []*model.Game { - games := make([]*model.Game, 0) - b, err := db.Cache.Get(cacheKeyGames) - if err != nil { - return games - } - err = json.Unmarshal(b, &games) - if err != nil { - utils.GetLogger().WithError(err).Error("Error while unmarshal fake users") - } - return games -} - -func (db *DatabaseFake) GetAllGames() ([]*model.Game, error) { - return db.loadGames(), nil -} - -func (db *DatabaseFake) GetGameByID(gameID string) (*model.Game, error) { - games := db.loadGames() - for _, g := range games { - if g.ID == gameID { - return g, nil - } - } - return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("game not found")) -} - -func (db *DatabaseFake) CreateGame(game *model.Game) error { - game.ID = uuid.NewV4().String() - - games := db.loadGames() - games = append(games, game) - db.saveGames(games) - return nil -} - -func (db *DatabaseFake) DeleteGame(string) error { - return nil -} - -func (db *DatabaseFake) UpdateGame(*model.Game) error { - return nil -} - -func (db *DatabaseFake) GetHamstersOfGame(game string) ([]*model.Hamster, error) { - hamsters := db.loadHamsters() - var hamstersFound []*model.Hamster - for _, g := range hamsters { - if g.Cage.Game.ID == game { - hamstersFound = append(hamstersFound, g) - } - } - return hamstersFound, nil -} diff --git a/storage/dao/fake/database_fake_hamsters.go b/storage/dao/fake/database_fake_hamsters.go deleted file mode 100755 index c10030b..0000000 --- a/storage/dao/fake/database_fake_hamsters.go +++ /dev/null @@ -1,73 +0,0 @@ -package fake - -import ( - "encoding/json" - "errors" - uuid "github.com/satori/go.uuid" - "hamster-tycoon/storage/dao" - "hamster-tycoon/storage/model" - "hamster-tycoon/utils" -) - -const ( - cacheKeyHamsters = "hamsters" -) - -func (db *DatabaseFake) saveHamsters(hamsters []*model.Hamster) { - data := make([]interface{}, 0) - for _, v := range hamsters { - data = append(data, v) - } - db.save(cacheKeyHamsters, data) -} - -func (db *DatabaseFake) loadHamsters() []*model.Hamster { - hamsters := make([]*model.Hamster, 0) - b, err := db.Cache.Get(cacheKeyHamsters) - if err != nil { - return hamsters - } - err = json.Unmarshal(b, &hamsters) - if err != nil { - utils.GetLogger().WithError(err).Error("Error while unmarshal fake users") - } - return hamsters -} - -func (db *DatabaseFake) GetAllHamsters(gameID, cageID string) ([]*model.Hamster, error) { - hamsters := db.loadHamsters() - var hamsterFound []*model.Hamster - for _, g := range hamsters { - if g.Cage.ID == cageID && g.Cage.Game.ID == gameID { - hamsterFound = append(hamsterFound, g) - } - } - return hamsterFound, nil -} - -func (db *DatabaseFake) GetHamsterByID(hamsterID, gameID, cageID string) (*model.Hamster, error) { - hamsters := db.loadHamsters() - for _, g := range hamsters { - if g.ID == hamsterID && g.Cage.ID == cageID && g.Cage.Game.ID == gameID { - return g, nil - } - } - return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("hamster not found")) -} - -func (db *DatabaseFake) CreateHamster(hamster *model.Hamster) error { - hamster.ID = uuid.NewV4().String() - - hamsters := db.loadHamsters() - hamsters = append(hamsters, hamster) - db.saveHamsters(hamsters) - return nil -} - -func (db *DatabaseFake) DeleteHamster(string) error { - return nil -} - -func (db *DatabaseFake) UpdateHamster(*model.Hamster) error { - return nil -} diff --git a/storage/dao/fake/database_fake_users.go b/storage/dao/fake/database_fake_users.go deleted file mode 100755 index ad24452..0000000 --- a/storage/dao/fake/database_fake_users.go +++ /dev/null @@ -1,106 +0,0 @@ -package fake - -import ( - "encoding/json" - "errors" - "hamster-tycoon/storage/dao" - "hamster-tycoon/storage/model" - "hamster-tycoon/utils" - "time" - - "github.com/satori/go.uuid" -) - -const ( - cacheKeyUsers = "users" -) - -func (db *DatabaseFake) saveUsers(users []*model.User) { - data := make([]interface{}, 0) - for _, v := range users { - data = append(data, v) - } - db.save(cacheKeyUsers, data) -} - -func (db *DatabaseFake) loadUsers() []*model.User { - users := make([]*model.User, 0) - b, err := db.Cache.Get(cacheKeyUsers) - if err != nil { - return users - } - err = json.Unmarshal(b, &users) - if err != nil { - utils.GetLogger().WithError(err).Error("Error while unmarshal fake users") - } - return users -} - -func (db *DatabaseFake) GetAllUsers() ([]*model.User, error) { - return db.loadUsers(), nil -} - -func (db *DatabaseFake) GetUsersByID(userID string) (*model.User, error) { - users := db.loadUsers() - for _, u := range users { - if u.ID == userID { - return u, nil - } - } - return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("user not found")) -} - -func (db *DatabaseFake) CreateUser(user *model.User) error { - user.ID = uuid.NewV4().String() - user.CreatedAt = time.Now() - - users := db.loadUsers() - users = append(users, user) - db.saveUsers(users) - return nil -} - -func (db *DatabaseFake) DeleteUser(userID string) error { - users := db.loadUsers() - newUsers := make([]*model.User, 0) - for _, u := range users { - if u.ID != userID { - newUsers = append(newUsers, u) - } - } - db.saveUsers(newUsers) - return nil -} - -func (db *DatabaseFake) UpdateUser(user *model.User) error { - users := db.loadUsers() - var foundUser *model.User - for _, u := range users { - if u.ID == user.ID { - foundUser = u - break - } - } - - if foundUser == nil { - return dao.NewDAOError(dao.ErrTypeNotFound, errors.New("user not found")) - } - - foundUser.UserEditable = user.UserEditable - now := time.Now() - foundUser.UpdatedAt = &now - db.saveUsers(users) - - *user = *foundUser - return nil -} - -func (db *DatabaseFake) GetUsersByGoogleID(userID string) (*model.User, error) { - users := db.loadUsers() - for _, u := range users { - if u.GoogleID == userID { - return u, nil - } - } - return nil, dao.NewDAOError(dao.ErrTypeNotFound, errors.New("user not found")) -} diff --git a/storage/dao/postgresql/database_postgresql_cages.go b/storage/dao/postgresql/database_postgresql_cages.go index c64d3f1..5ec92d2 100755 --- a/storage/dao/postgresql/database_postgresql_cages.go +++ b/storage/dao/postgresql/database_postgresql_cages.go @@ -2,18 +2,18 @@ package postgresql import ( "database/sql" - "github.com/lib/pq" "hamster-tycoon/storage/dao" "hamster-tycoon/storage/model" + + "github.com/lib/pq" ) -func (db *DatabasePostgreSQL) GetAllCages(gameID string) ([]*model.Cage, error) { +func (db *DatabasePostgreSQL) GetAllCages() ([]*model.Cage, error) { q := ` - SELECT c.id, created_at, updated_at, game_id + SELECT c.id, created_at, updated_at FROM public.Cage c - WHERE c.game_id=$1 ` - rows, err := db.session.Query(q, gameID) + rows, err := db.session.Query(q) if err != nil { return nil, err } @@ -21,11 +21,8 @@ func (db *DatabasePostgreSQL) GetAllCages(gameID string) ([]*model.Cage, error) cages := make([]*model.Cage, 0) for rows.Next() { - game := model.Game{} - cage := model.Cage{ - Game: game, - } - err := rows.Scan(&cage.ID, &cage.CreatedAt, &cage.UpdatedAt, &game.ID) + cage := model.Cage{} + err := rows.Scan(&cage.ID, &cage.CreatedAt, &cage.UpdatedAt) if err != nil { return nil, err } @@ -34,19 +31,16 @@ func (db *DatabasePostgreSQL) GetAllCages(gameID string) ([]*model.Cage, error) return cages, nil } -func (db *DatabasePostgreSQL) GetCageByID(gameID, cageID string) (*model.Cage, error) { +func (db *DatabasePostgreSQL) GetCageByID(cageID string) (*model.Cage, error) { q := ` - SELECT c.id, created_at, updated_at, game_id + SELECT c.id, created_at, updated_at FROM public.Cage c - WHERE c.game_id=$1 and c.id = $2 + WHERE c.id = $2 ` - row := db.session.QueryRow(q, gameID, cageID) + row := db.session.QueryRow(q, cageID) - game := model.Game{} - cage := model.Cage{ - Game: game, - } - err := row.Scan(&cage.ID, &cage.CreatedAt, &cage.UpdatedAt, &game.ID) + cage := model.Cage{} + err := row.Scan(&cage.ID, &cage.CreatedAt, &cage.UpdatedAt) if errPq, ok := err.(*pq.Error); ok { return nil, handlePgError(errPq) } @@ -57,21 +51,7 @@ func (db *DatabasePostgreSQL) GetCageByID(gameID, cageID string) (*model.Cage, e } func (db *DatabasePostgreSQL) CreateCage(cage *model.Cage) error { - q := ` - INSERT INTO public.Cage - (game_id) - VALUES - ($1) - RETURNING id, created_at - ` - - err := db.session. - QueryRow(q, cage.Game.ID). - Scan(&cage.ID, &cage.CreatedAt) - if errPq, ok := err.(*pq.Error); ok { - return handlePgError(errPq) - } - return err + return nil } func (db *DatabasePostgreSQL) DeleteCage(id string) error { diff --git a/storage/dao/postgresql/database_postgresql_games.go b/storage/dao/postgresql/database_postgresql_games.go deleted file mode 100755 index 4ce5d0a..0000000 --- a/storage/dao/postgresql/database_postgresql_games.go +++ /dev/null @@ -1,127 +0,0 @@ -package postgresql - -import ( - "database/sql" - "github.com/lib/pq" - "hamster-tycoon/storage/dao" - "hamster-tycoon/storage/model" -) - -func (db *DatabasePostgreSQL) GetAllGames() ([]*model.Game, error) { - q := ` - SELECT g.id, g.name, g.user_id, g.created_at, g.updated_at - FROM public.game g - ` - rows, err := db.session.Query(q) - if err != nil { - return nil, err - } - defer rows.Close() - - games := make([]*model.Game, 0) - for rows.Next() { - user := model.User{} - game := model.Game{} - err := rows.Scan(&game.ID, &game.Name, &user.ID, &game.CreatedAt, &game.UpdatedAt) - if err != nil { - return nil, err - } - games = append(games, &game) - } - return games, nil -} - -func (db *DatabasePostgreSQL) GetGameByID(id string) (*model.Game, error) { - q := ` - SELECT g.id, g.name, g.user_id, g.created_at, g.updated_at - FROM public.game g - WHERE g.id = $1 - ` - row := db.session.QueryRow(q, id) - user := model.User{} - game := model.Game{} - err := row.Scan(&game.ID, &game.Name, &user.ID, &game.CreatedAt, &game.UpdatedAt) - if errPq, ok := err.(*pq.Error); ok { - return nil, handlePgError(errPq) - } - if err == sql.ErrNoRows { - return nil, dao.NewDAOError(dao.ErrTypeNotFound, err) - } - return &game, err -} - -func (db *DatabasePostgreSQL) CreateGame(game *model.Game) error { - q := ` - INSERT INTO public.game - (user_id, name) - VALUES - ($1, $2) - RETURNING id, created_at - ` - - err := db.session. - QueryRow(q, game.User.ID, game.Name). - Scan(&game.ID, &game.CreatedAt) - if errPq, ok := err.(*pq.Error); ok { - return handlePgError(errPq) - } - return err -} - -func (db *DatabasePostgreSQL) DeleteGame(id string) error { - q := ` - DELETE FROM public.game - WHERE id = $1 - ` - - _, err := db.session.Exec(q, id) - if errPq, ok := err.(*pq.Error); ok { - return handlePgError(errPq) - } - return err -} - -func (db *DatabasePostgreSQL) GetHamstersOfGame(gameID string) ([]*model.Hamster, error) { - q := ` - SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, gestation, gestation_period, gestation_cooldown, gestation_father_id - FROM public.Hamster h - JOIN public.cage c - ON c.id = h.cage_id - JOIN public.game g - on c.game_id = g.id - WHERE g.id = $1 - ` - rows, err := db.session.Query(q, gameID) - if err != nil { - return nil, err - } - defer rows.Close() - - hamsters := make([]*model.Hamster, 0) - for rows.Next() { - hamster := model.Hamster{ - Mother: &model.Hamster{}, - Father: &model.Hamster{}, - GestationFather: &model.Hamster{}, - } - err := rows.Scan(&hamster.ID, &hamster.CreatedAt, - &hamster.UpdatedAt, &hamster.Name, - &hamster.Number, &hamster.Sexe, - &hamster.Age, &hamster.Father.ID, - &hamster.Mother.ID, &hamster.HungerLevel, - &hamster.ThirstLevel, &hamster.Weight, - &hamster.Height, &hamster.Alive, - &hamster.Sold, &hamster.Gestation, - &hamster.GestationPeriod, &hamster.GestationCooldown, - &hamster.GestationFather.ID) - if err != nil { - return nil, err - } - hamsters = append(hamsters, &hamster) - } - return hamsters, nil -} - -func (db *DatabasePostgreSQL) UpdateGame(*model.Game) error { - return nil -} diff --git a/storage/dao/postgresql/database_postgresql_hamsters.go b/storage/dao/postgresql/database_postgresql_hamsters.go index 57902ee..bf3f270 100755 --- a/storage/dao/postgresql/database_postgresql_hamsters.go +++ b/storage/dao/postgresql/database_postgresql_hamsters.go @@ -2,20 +2,20 @@ package postgresql import ( "database/sql" - "github.com/lib/pq" "hamster-tycoon/storage/dao" "hamster-tycoon/storage/model" + + "github.com/lib/pq" ) -func (db *DatabasePostgreSQL) GetAllHamsters(gameID, cageID string) ([]*model.Hamster, error) { +func (db *DatabasePostgreSQL) GetAllHamsters(cageID string) ([]*model.Hamster, error) { q := ` - SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, gestation, gestation_period, gestation_cooldown, gestation_father_id, cage_id + SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, golden, gestation, gestation_period, gestation_cooldown, gestation_father_id, cage_id FROM hamster h JOIN cage c ON h.cage_id = c.id - JOIN game g on c.game_id = g.id WHERE c.id=$1 and g.id=$2 ` - rows, err := db.session.Query(q, cageID, gameID) + rows, err := db.session.Query(q, cageID) if err != nil { return nil, err } @@ -36,7 +36,7 @@ func (db *DatabasePostgreSQL) GetAllHamsters(gameID, cageID string) ([]*model.Ha &hamster.Mother.ID, &hamster.HungerLevel, &hamster.ThirstLevel, &hamster.Weight, &hamster.Height, &hamster.Alive, - &hamster.Sold, &hamster.Gestation, + &hamster.Sold, &hamster.Golden, &hamster.Gestation, &hamster.GestationPeriod, &hamster.GestationCooldown, &hamster.GestationFather.ID, &hamster.Cage.ID) if err != nil { @@ -47,15 +47,14 @@ func (db *DatabasePostgreSQL) GetAllHamsters(gameID, cageID string) ([]*model.Ha return hamsters, nil } -func (db *DatabasePostgreSQL) GetHamsterByID(id, gameID, cageID string) (*model.Hamster, error) { +func (db *DatabasePostgreSQL) GetHamsterByID(id, cageID string) (*model.Hamster, error) { q := ` - SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, gestation, gestation_period, gestation_cooldown, gestation_father_id, cage_id + SELECT id, created_at, updated_at, name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, golden, gestation, gestation_period, gestation_cooldown, gestation_father_id, cage_id FROM hamster h JOIN cage c ON h.cage_id = c.id - JOIN game g on c.game_id = g.id WHERE h.id=$1 and c.id=$2 and g.id=$3 ` - row := db.session.QueryRow(q, id, cageID, gameID) + row := db.session.QueryRow(q, id, cageID) hamster := model.Hamster{ Mother: &model.Hamster{}, @@ -70,7 +69,7 @@ func (db *DatabasePostgreSQL) GetHamsterByID(id, gameID, cageID string) (*model. &hamster.Mother.ID, &hamster.HungerLevel, &hamster.ThirstLevel, &hamster.Weight, &hamster.Height, &hamster.Alive, - &hamster.Sold, &hamster.Gestation, + &hamster.Sold, &hamster.Golden, &hamster.Gestation, &hamster.GestationPeriod, &hamster.GestationCooldown, &hamster.GestationFather.ID, &hamster.Cage.ID) @@ -86,7 +85,7 @@ func (db *DatabasePostgreSQL) GetHamsterByID(id, gameID, cageID string) (*model. func (db *DatabasePostgreSQL) CreateHamster(hamster *model.Hamster) error { q := ` INSERT INTO public.Hamster - (name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, gestation, gestation_period, gestation_cooldown, gestation_father_id,cage_id) + (name, number, sexe, age, father_id, mother_id, hunger_level, thirst_level, weight, height, alive, sold, golden, gestation, gestation_period, gestation_cooldown, gestation_father_id,cage_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) RETURNING id, created_at @@ -99,7 +98,7 @@ func (db *DatabasePostgreSQL) CreateHamster(hamster *model.Hamster) error { &hamster.Mother.ID, &hamster.HungerLevel, &hamster.ThirstLevel, &hamster.Weight, &hamster.Height, &hamster.Alive, - &hamster.Sold, &hamster.Gestation, + &hamster.Sold, &hamster.Golden, &hamster.Gestation, &hamster.GestationPeriod, &hamster.GestationCooldown, &hamster.GestationFather.ID, &hamster.Cage.ID). Scan(&hamster.ID, &hamster.CreatedAt) diff --git a/storage/model/cage.go b/storage/model/cage.go index c6ff01c..4992312 100644 --- a/storage/model/cage.go +++ b/storage/model/cage.go @@ -4,7 +4,6 @@ import "time" type Cage struct { ID string `json:"id"` - Game Game `json:"game"` Hamsters []*Hamster `json:"hamsters"` CreatedAt time.Time `json:"createdAt"` UpdatedAt *time.Time `json:"updatedAt"` diff --git a/storage/model/game.go b/storage/model/game.go deleted file mode 100644 index ee23fc2..0000000 --- a/storage/model/game.go +++ /dev/null @@ -1,13 +0,0 @@ -package model - -import "time" - -type Game struct { - ID string `json:"game_id"` - User User `json:"-"` - Name string `json:"name"` - Cages []*Cage `json:"cages"` - SoldHamster []*Hamster `json:"sold_hamsters"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt *time.Time `json:"updatedAt"` -} diff --git a/storage/model/user.go b/storage/model/user.go index f7ec5a9..0c299fd 100755 --- a/storage/model/user.go +++ b/storage/model/user.go @@ -10,7 +10,6 @@ type User struct { CreatedAt time.Time `json:"createdAt"` UpdatedAt *time.Time `json:"updatedAt"` GoogleID string `json:"-"` - Games []Game } type UserEditable struct {