package main import ( "encoding/json" "strconv" "github.com/julienschmidt/httprouter" ) func init() { router.GET("/api/questions/:qid/proposals", apiAuthHandler(questionAuthHandler( func(q Question, u *User, _ []byte) HTTPResponse { return formatApiResponse(q.GetProposals()) }), loggedUser)) router.GET("/api/surveys/:sid/questions/:qid/proposals", apiAuthHandler(questionAuthHandler( func(q Question, u *User, _ []byte) HTTPResponse { return formatApiResponse(q.GetProposals()) }), loggedUser)) router.POST("/api/surveys/:sid/questions/:qid/proposals", apiAuthHandler(questionAuthHandler(func(q Question, u *User, body []byte) HTTPResponse { var new Proposal if err := json.Unmarshal(body, &new); err != nil { return APIErrorResponse{err: err} } return formatApiResponse(q.NewProposal(new.Label)) }), adminRestricted)) router.PUT("/api/surveys/:sid/questions/:qid/proposals/:pid", apiAuthHandler(proposalAuthHandler(func(current Proposal, u *User, body []byte) HTTPResponse { var new Proposal if err := json.Unmarshal(body, &new); err != nil { return APIErrorResponse{err: err} } new.Id = current.Id return formatApiResponse(new.Update()) }), adminRestricted)) router.DELETE("/api/surveys/:sid/questions/:qid/proposals/:pid", apiAuthHandler(proposalAuthHandler(func(p Proposal, u *User, body []byte) HTTPResponse { return formatApiResponse(p.Delete()) }), adminRestricted)) } func proposalHandler(f func(Proposal, []byte) HTTPResponse) func(httprouter.Params, []byte) HTTPResponse { return func(ps httprouter.Params, body []byte) HTTPResponse { var question *Question = nil if qid, err := strconv.Atoi(string(ps.ByName("qid"))); err == nil { if q, err := getQuestion(qid); err == nil { question = &q } } if pid, err := strconv.Atoi(string(ps.ByName("pid"))); err != nil { return APIErrorResponse{err: err} } else if question == nil { if proposal, err := getProposal(pid); err != nil { return APIErrorResponse{err: err} } else { return f(proposal, body) } } else { if proposal, err := question.GetProposal(pid); err != nil { return APIErrorResponse{err: err} } else { return f(proposal, body) } } } } func proposalAuthHandler(f func(Proposal, *User, []byte) HTTPResponse) func(*User, httprouter.Params, []byte) HTTPResponse { return func(u *User, ps httprouter.Params, body []byte) HTTPResponse { return proposalHandler(func(p Proposal, body []byte) HTTPResponse { return f(p, u, body) })(ps, body) } } 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) { 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) { 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 } }