188 lines
6.6 KiB
Go
188 lines
6.6 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"net/http"
|
||
|
"time"
|
||
|
"strconv"
|
||
|
|
||
|
"github.com/julienschmidt/httprouter"
|
||
|
)
|
||
|
|
||
|
func init() {
|
||
|
router.POST("/api/surveys/:sid", apiAuthHandler(surveyAuthHandler(func(s Survey, u *User, body []byte) HTTPResponse {
|
||
|
var responses []Response
|
||
|
if err := json.Unmarshal(body, &responses); err != nil {
|
||
|
return APIErrorResponse{err:err}
|
||
|
}
|
||
|
|
||
|
for _, response := range responses {
|
||
|
if _, err := s.NewResponse(response.IdQuestion, u.Id, response.Answer); err != nil {
|
||
|
return APIErrorResponse{err:err}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return APIResponse{true}
|
||
|
})))
|
||
|
router.GET("/api/surveys/:sid/responses", apiAuthHandler(surveyAuthHandler(
|
||
|
func(s Survey, u *User, _ []byte) HTTPResponse {
|
||
|
return formatApiResponse(s.GetMyResponses(u))
|
||
|
})))
|
||
|
router.GET("/api/surveys/:sid/responses/:rid", apiAuthHandler(responseAuthHandler(
|
||
|
func(r Response, _ *User, _ []byte) HTTPResponse {
|
||
|
return APIResponse{r}
|
||
|
})))
|
||
|
router.PUT("/api/surveys/:sid/responses/:rid", apiAuthHandler(responseAuthHandler(func(current Response, u *User, body []byte) HTTPResponse {
|
||
|
if u.Id != current.IdUser && !u.IsAdmin {
|
||
|
return APIErrorResponse{
|
||
|
status: http.StatusForbidden,
|
||
|
err: errors.New("Not Authorized"),
|
||
|
}
|
||
|
}
|
||
|
var new Response
|
||
|
if err := json.Unmarshal(body, &new); err != nil {
|
||
|
return APIErrorResponse{err:err}
|
||
|
}
|
||
|
|
||
|
new.Id = current.Id
|
||
|
new.IdUser = current.IdUser
|
||
|
return formatApiResponse(new.Update())
|
||
|
})))
|
||
|
}
|
||
|
|
||
|
func responseHandler(f func(Response, []byte) HTTPResponse) func(httprouter.Params, []byte) HTTPResponse {
|
||
|
return func(ps httprouter.Params, body []byte) HTTPResponse {
|
||
|
var survey *Survey = nil
|
||
|
|
||
|
if sid, err := strconv.Atoi(string(ps.ByName("sid"))); err == nil {
|
||
|
if s, err := getSurvey(sid); err == nil {
|
||
|
survey = &s
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if rid, err := strconv.Atoi(string(ps.ByName("rid"))); err != nil {
|
||
|
return APIErrorResponse{err:err}
|
||
|
} else if survey == nil {
|
||
|
if response, err := getResponse(rid); err != nil {
|
||
|
return APIErrorResponse{err:err}
|
||
|
} else {
|
||
|
return f(response, body)
|
||
|
}
|
||
|
} else {
|
||
|
if response, err := survey.GetResponse(rid); err != nil {
|
||
|
return APIErrorResponse{err:err}
|
||
|
} else {
|
||
|
return f(response, body)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func responseAuthHandler(f func(Response, *User, []byte) HTTPResponse) func(*User, httprouter.Params, []byte) HTTPResponse {
|
||
|
return func(u *User, ps httprouter.Params, body []byte) HTTPResponse {
|
||
|
return responseHandler(func(r Response, body []byte) HTTPResponse {
|
||
|
return f(r, u, body)
|
||
|
})(ps, body)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type Response struct {
|
||
|
Id int64 `json:"id"`
|
||
|
IdQuestion int64 `json:"id_question"`
|
||
|
IdUser int64 `json:"id_user"`
|
||
|
Answer string `json:"value"`
|
||
|
TimeSubmit time.Time `json:"time_submit"`
|
||
|
Score *int64 `json:"score,omitempty"`
|
||
|
ScoreExplanation *string `json:"score_explanation,omitempty"`
|
||
|
IdCorrector *int64 `json:"id_corrector,omitempty"`
|
||
|
TimeScored *time.Time `json:"time_scored,omitempty"`
|
||
|
}
|
||
|
|
||
|
func (s *Survey) GetResponses() (responses []Response, err error) {
|
||
|
if rows, errr := DBQuery("SELECT R.id_response, R.id_question, R.id_user, R.answer, R.time_submit, R.score, R.score_explanation, R.id_corrector, R.time_scored FROM survey_responses R INNER JOIN survey_quests Q ON Q.id_question = R.id_question WHERE Q.id_survey=?", s.Id); errr != nil {
|
||
|
return nil, errr
|
||
|
} else {
|
||
|
defer rows.Close()
|
||
|
|
||
|
for rows.Next() {
|
||
|
var r Response
|
||
|
if err = rows.Scan(&r.Id, &r.IdQuestion, &r.IdUser, &r.TimeSubmit, &r.Score, &r.ScoreExplanation, &r.IdCorrector, &r.TimeScored); err != nil {
|
||
|
return
|
||
|
}
|
||
|
responses = append(responses, r)
|
||
|
}
|
||
|
if err = rows.Err(); err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *Survey) GetMyResponses(u *User) (responses []Response, err error) {
|
||
|
if rows, errr := DBQuery("SELECT R.id_response, R.id_question, R.id_user, R.answer, R.time_submit, R.score, R.score_explanation, R.id_corrector, R.time_scored FROM survey_responses R INNER JOIN survey_quests Q ON Q.id_question = R.id_question WHERE Q.id_survey=? AND R.id_user=? ORDER BY time_submit DESC", s.Id, u.Id); errr != nil {
|
||
|
return nil, errr
|
||
|
} else {
|
||
|
defer rows.Close()
|
||
|
|
||
|
for rows.Next() {
|
||
|
var r Response
|
||
|
if err = rows.Scan(&r.Id, &r.IdQuestion, &r.IdUser, &r.TimeSubmit, &r.Score, &r.ScoreExplanation, &r.IdCorrector, &r.TimeScored); err != nil {
|
||
|
return
|
||
|
}
|
||
|
responses = append(responses, r)
|
||
|
}
|
||
|
if err = rows.Err(); err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func getResponse(id int) (r Response, err error) {
|
||
|
err = DBQueryRow("SELECT id_response, id_question, id_user, answer, time_submit, score, score_explanation, id_corrector, time_scored FROM survey_responses WHERE id_response=?", id).Scan(&r.Id, &r.IdQuestion, &r.IdUser, &r.TimeSubmit, &r.Score, &r.ScoreExplanation, &r.IdCorrector, &r.TimeScored)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Survey) GetResponse(id int) (r Response, err error) {
|
||
|
err = DBQueryRow("SELECT R.id_response, R.id_question, R.id_user, R.answer, R.time_submit, R.score, R.score_explanation, R.id_corrector, R.time_scored FROM survey_responses R INNER JOIN survey_quests Q ON Q.id_question = R.id_question WHERE R.id_response=? AND Q.id_survey=?", id, s.Id).Scan(&r.Id, &r.IdQuestion, &r.IdUser, &r.TimeSubmit, &r.Score, &r.ScoreExplanation, &r.IdCorrector, &r.TimeScored)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Survey) NewResponse(id_question int64, id_user int64, response string) (Response, error) {
|
||
|
if res, err := DBExec("INSERT INTO survey_responses (id_question, id_user, answer, time_submit) VALUES (?, ?, ?, ?)", id_question, id_user, response, time.Now()); err != nil {
|
||
|
return Response{}, err
|
||
|
} else if rid, err := res.LastInsertId(); err != nil {
|
||
|
return Response{}, err
|
||
|
} else {
|
||
|
return Response{rid, id_question, id_user, response, time.Now(), nil, nil, nil, nil}, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (r Response) Update() (Response, error) {
|
||
|
_, err := DBExec("UPDATE survey_responses SET id_question = ?, id_user = ?, answer = ?, time_submit = ?, score = ?, score_explanation = ?, id_corrector = ?, time_scored = ? WHERE id_response = ?", r.IdQuestion, r.IdUser, r.Answer, r.TimeSubmit, r.Score, r.ScoreExplanation, r.IdCorrector, r.TimeScored, r.Id)
|
||
|
return r, err
|
||
|
}
|
||
|
|
||
|
func (r Response) Delete() (int64, error) {
|
||
|
if res, err := DBExec("DELETE FROM survey_responses WHERE id_response = ?", r.Id); err != nil {
|
||
|
return 0, err
|
||
|
} else if nb, err := res.RowsAffected(); err != nil {
|
||
|
return 0, err
|
||
|
} else {
|
||
|
return nb, err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func ClearResponses() (int64, error) {
|
||
|
if res, err := DBExec("DELETE FROM survey_responses"); err != nil {
|
||
|
return 0, err
|
||
|
} else if nb, err := res.RowsAffected(); err != nil {
|
||
|
return 0, err
|
||
|
} else {
|
||
|
return nb, err
|
||
|
}
|
||
|
}
|