package main import ( "log" "net/http" "strconv" "github.com/gin-gonic/gin" ) func declareAPIAuthProposalsRoutes(router *gin.RouterGroup) { router.GET("/proposals", func(c *gin.Context) { q := c.MustGet("question").(*Question) proposals, err := q.GetProposals() if err != nil { log.Printf("Unable to GetProposals(qid=%d): %s", q.Id, err.Error()) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs during proposals retrieving"}) return } c.JSON(http.StatusOK, proposals) }) } func declareAPIAdminProposalsRoutes(router *gin.RouterGroup) { router.POST("/proposals", func(c *gin.Context) { q := c.MustGet("question").(*Question) var new Proposal if err := c.ShouldBindJSON(&new); err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()}) return } proposal, err := q.NewProposal(new.Label) if err != nil { log.Printf("Unable to NewProposal(qid=%d): %s", q.Id, err.Error()) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when trying to insert new proposal."}) return } c.JSON(http.StatusOK, proposal) }) proposalsRoutes := router.Group("/proposals/:pid") proposalsRoutes.Use(proposalHandler) proposalsRoutes.PUT("", func(c *gin.Context) { current := c.MustGet("proposal").(*Proposal) var new Proposal if err := c.ShouldBindJSON(&new); err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()}) return } new.Id = current.Id proposal, err := new.Update() if err != nil { log.Println("Unable to Update proposal:", err) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs during proposal updating."}) return } c.JSON(http.StatusOK, proposal) }) proposalsRoutes.DELETE("", func(c *gin.Context) { p := c.MustGet("proposal").(*Proposal) if _, err := p.Delete(); err != nil { log.Printf("Unable to Delete(pid=%d) proposal: %s", p.Id, err.Error()) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when trying to delete proposal."}) return } c.JSON(http.StatusOK, nil) }) } func proposalHandler(c *gin.Context) { var question *Question = nil if q, ok := c.Get("question"); ok { question = q.(*Question) } var proposal *Proposal if pid, err := strconv.Atoi(string(c.Param("pid"))); err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Invalid proposal ID"}) return } else if question == nil { if proposal, err = getProposal(pid); err != nil { c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Proposal not found"}) return } } else { if proposal, err = question.GetProposal(pid); err != nil { c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Proposal not found"}) return } } if proposal == nil { c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Proposal not found"}) return } else { c.Set("proposal", proposal) c.Next() } } type Proposal struct { Id int64 `json:"id"` IdQuestion int64 `json:"id_question"` Label string `json:"label"` } func (q *Question) GetProposals() (proposals []*Proposal, err error) { if rows, errr := DBQuery("SELECT id_proposal, id_question, label FROM survey_proposals WHERE id_question=?", q.Id); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { var p Proposal if err = rows.Scan(&p.Id, &p.IdQuestion, &p.Label); err != nil { return } proposals = append(proposals, &p) } if err = rows.Err(); err != nil { return } return } } func getProposal(id int) (p *Proposal, err error) { p = new(Proposal) err = DBQueryRow("SELECT id_proposal, id_question, label FROM survey_proposals WHERE id_proposal=?", id).Scan(&p.Id, &p.IdQuestion, &p.Label) return } func (q *Question) GetProposal(id int) (p *Proposal, err error) { p = new(Proposal) err = DBQueryRow("SELECT id_proposal, id_question, label FROM survey_proposals WHERE id_proposal=? AND id_question=?", id, q.Id).Scan(&p.Id, &p.IdQuestion, &p.Label) return } func (q *Question) NewProposal(label string) (Proposal, error) { if res, err := DBExec("INSERT INTO survey_proposals (id_question, label) VALUES (?, ?)", q.Id, label); err != nil { return Proposal{}, err } else if pid, err := res.LastInsertId(); err != nil { return Proposal{}, err } else { return Proposal{pid, q.Id, label}, nil } } func (p Proposal) Update() (Proposal, error) { _, err := DBExec("UPDATE survey_proposals SET id_question = ?, label = ? WHERE id_proposal = ?", p.IdQuestion, p.Label, p.Id) return p, err } func (p Proposal) Delete() (int64, error) { if res, err := DBExec("DELETE FROM survey_proposals WHERE id_proposal = ?", p.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err } else { return nb, err } } func ClearProposals() (int64, error) { if res, err := DBExec("DELETE FROM survey_proposals"); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err } else { return nb, err } }