package main import ( "fmt" "log" "net/http" "strconv" "github.com/gin-gonic/gin" ) func declareAPICategoriesRoutes(router *gin.RouterGroup) { categoriesRoutes := router.Group("/categories/:cid") categoriesRoutes.Use(categoryHandler) categoriesRoutes.GET("", func(c *gin.Context) { c.JSON(http.StatusOK, c.MustGet("category").(*Category)) }) } func declareAPIAdminCategoriesRoutes(router *gin.RouterGroup) { router.GET("categories", func(c *gin.Context) { categories, err := getCategories() if err != nil { log.Println("Unable to getCategories:", err) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrieve categories. Please try again later."}) return } c.JSON(http.StatusOK, categories) }) router.POST("categories", func(c *gin.Context) { var new Category if err := c.ShouldBindJSON(&new); err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()}) return } if new.Promo == 0 { new.Promo = currentPromo } if cat, err := NewCategory(new.Label, new.Promo, new.Expand); err != nil { log.Println("Unable to NewCategory:", err) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs during category creation: %s", err.Error())}) return } else { c.JSON(http.StatusOK, cat) } }) categoriesRoutes := router.Group("/categories/:cid") categoriesRoutes.Use(categoryHandler) categoriesRoutes.PUT("", func(c *gin.Context) { current := c.MustGet("category").(*Category) var new Category if err := c.ShouldBindJSON(&new); err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()}) return } new.Id = current.Id if _, err := new.Update(); err != nil { log.Println("Unable to Update category:", err) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to update the given category. Please try again later."}) return } else { c.JSON(http.StatusOK, new) } }) categoriesRoutes.DELETE("", func(c *gin.Context) { current := c.MustGet("category").(*Category) if _, err := current.Delete(); err != nil { log.Println("Unable to Delete category:", err) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to delete the given category. Please try again later."}) return } else { c.JSON(http.StatusOK, nil) } }) } func categoryHandler(c *gin.Context) { var category *Category cid, err := strconv.Atoi(string(c.Param("cid"))) if err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Bad category identifier."}) return } else { category, err = getCategory(cid) if err != nil { c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Category not found."}) return } } c.Set("category", category) c.Next() } type Category struct { Id int64 `json:"id"` Label string `json:"label"` Promo uint `json:"promo"` Expand bool `json:"expand,omitempty"` } func getCategories() (categories []Category, err error) { if rows, errr := DBQuery("SELECT id_category, label, promo, expand FROM categories ORDER BY promo DESC, expand DESC, id_category DESC"); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { var c Category if err = rows.Scan(&c.Id, &c.Label, &c.Promo, &c.Expand); err != nil { return } categories = append(categories, c) } if err = rows.Err(); err != nil { return } return } } func getCategory(id int) (c *Category, err error) { c = new(Category) err = DBQueryRow("SELECT id_category, label, promo, expand FROM categories WHERE id_category=?", id).Scan(&c.Id, &c.Label, &c.Promo, &c.Expand) return } func NewCategory(label string, promo uint, expand bool) (*Category, error) { if res, err := DBExec("INSERT INTO categories (label, promo, expand) VALUES (?, ?, ?)", label, promo, expand); err != nil { return nil, err } else if cid, err := res.LastInsertId(); err != nil { return nil, err } else { return &Category{cid, label, promo, expand}, nil } } func (c *Category) Update() (int64, error) { if res, err := DBExec("UPDATE categories SET label = ?, promo = ?, expand = ? WHERE id_category = ?", c.Label, c.Promo, c.Expand, c.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err } else { return nb, err } } func (c *Category) Delete() (int64, error) { if res, err := DBExec("DELETE FROM categories WHERE id_category = ?", c.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err } else { return nb, err } }