2020-03-04 11:07:12 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-03-01 16:47:00 +00:00
|
|
|
"fmt"
|
2022-07-09 17:42:00 +00:00
|
|
|
"log"
|
2022-11-20 12:30:12 +00:00
|
|
|
"math"
|
2020-03-04 11:07:12 +00:00
|
|
|
"net/http"
|
|
|
|
"strconv"
|
2022-02-21 07:53:27 +00:00
|
|
|
"strings"
|
2022-09-02 12:08:03 +00:00
|
|
|
"sync"
|
2020-09-13 14:37:30 +00:00
|
|
|
"time"
|
2020-03-04 11:07:12 +00:00
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
2020-03-04 11:07:12 +00:00
|
|
|
)
|
|
|
|
|
2022-02-28 16:45:30 +00:00
|
|
|
var (
|
2022-09-02 12:08:03 +00:00
|
|
|
_score_cache = map[int64]map[int64]*float64{}
|
|
|
|
_score_cache_mutex = sync.RWMutex{}
|
|
|
|
_surveys_cache = map[int64]*Survey{}
|
|
|
|
_surveys_cache_mutex = sync.RWMutex{}
|
2022-02-28 16:45:30 +00:00
|
|
|
)
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
func declareAPISurveysRoutes(router *gin.RouterGroup) {
|
|
|
|
router.GET("/surveys", func(c *gin.Context) {
|
|
|
|
u := c.MustGet("LoggedUser").(*User)
|
2022-02-21 07:53:27 +00:00
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
var response []*Survey
|
|
|
|
var err error
|
|
|
|
if u == nil {
|
2022-09-02 10:00:21 +00:00
|
|
|
response, err = getSurveys(fmt.Sprintf("WHERE shown = TRUE AND NOW() > start_availability AND promo = %d ORDER BY start_availability ASC", currentPromo))
|
2022-07-09 17:42:00 +00:00
|
|
|
} else if u.IsAdmin {
|
|
|
|
response, err = getSurveys("ORDER BY promo DESC, start_availability ASC")
|
|
|
|
} else {
|
|
|
|
var surveys []*Survey
|
2022-09-02 10:00:21 +00:00
|
|
|
surveys, err = getSurveys(fmt.Sprintf("WHERE shown = TRUE AND promo = %d ORDER BY start_availability ASC", u.Promo))
|
2022-07-09 17:42:00 +00:00
|
|
|
if err == nil {
|
2022-02-21 07:53:27 +00:00
|
|
|
for _, s := range surveys {
|
|
|
|
if s.Group == "" || strings.Contains(u.Groups, ","+s.Group+",") {
|
2022-07-09 18:52:22 +00:00
|
|
|
s.Group = ""
|
2022-02-21 07:53:27 +00:00
|
|
|
response = append(response, s)
|
|
|
|
}
|
|
|
|
}
|
2022-07-09 17:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Impossible de lister les questionnaires. Veuillez réessayer dans quelques instants"})
|
|
|
|
log.Printf("Unable to list surveys: %s", err.Error())
|
|
|
|
} else {
|
|
|
|
c.JSON(http.StatusOK, response)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
surveysRoutes := router.Group("/surveys/:sid")
|
|
|
|
surveysRoutes.Use(surveyHandler)
|
2022-09-07 19:33:54 +00:00
|
|
|
surveysRoutes.Use(surveyUserAccessHandler)
|
2022-07-09 17:42:00 +00:00
|
|
|
|
|
|
|
surveysRoutes.GET("", func(c *gin.Context) {
|
|
|
|
u := c.MustGet("LoggedUser").(*User)
|
|
|
|
|
|
|
|
if u == nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"errmsg": "Veuillez vous connecter pour accéder à cette page."})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-11-19 10:41:35 +00:00
|
|
|
c.JSON(http.StatusOK, c.MustGet("survey").(*Survey))
|
2022-07-09 17:42:00 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func declareAPIAuthSurveysRoutes(router *gin.RouterGroup) {
|
|
|
|
surveysRoutes := router.Group("/surveys/:sid")
|
|
|
|
surveysRoutes.Use(surveyHandler)
|
2022-11-19 10:41:35 +00:00
|
|
|
surveysRoutes.Use(surveyUserAccessHandler)
|
2022-07-09 17:42:00 +00:00
|
|
|
|
|
|
|
surveysRoutes.GET("/score", func(c *gin.Context) {
|
|
|
|
var u *User
|
|
|
|
if user, ok := c.Get("user"); ok {
|
|
|
|
u = user.(*User)
|
|
|
|
} else {
|
2022-11-19 12:05:26 +00:00
|
|
|
u = c.MustGet("LoggedUser").(*User)
|
2022-07-09 17:42:00 +00:00
|
|
|
}
|
|
|
|
s := c.MustGet("survey").(*Survey)
|
|
|
|
|
2022-11-19 16:22:50 +00:00
|
|
|
if u.IsAdmin {
|
|
|
|
questions, err := s.GetQuestions()
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Unable to getQuestions:", err)
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrieve questions. Please try again later."})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
itemCount := 0
|
|
|
|
itemCorrected := 0
|
|
|
|
for _, q := range questions {
|
|
|
|
res, err := q.GetResponses()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Unable to GetResponses(qid=%d): %s", q.Id, err.Error())
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs during responses retrieval."})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, r := range res {
|
|
|
|
itemCount += 1
|
|
|
|
if r.TimeScored != nil && (r.TimeReported == nil || r.TimeScored.After(*r.TimeReported)) {
|
|
|
|
itemCorrected += 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, map[string]int{"count": itemCount, "corrected": itemCorrected})
|
|
|
|
} else if s.Promo == u.Promo && s.Shown {
|
2022-07-09 17:42:00 +00:00
|
|
|
score, err := s.GetScore(u)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Unable to GetScore(uid=%d;sid=%d): %s", u.Id, s.Id, err.Error())
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when trying to retrieve score."})
|
|
|
|
return
|
|
|
|
}
|
2022-02-21 07:53:27 +00:00
|
|
|
|
2022-11-19 12:05:26 +00:00
|
|
|
if score == nil {
|
2022-11-18 15:11:24 +00:00
|
|
|
c.JSON(http.StatusOK, map[string]string{"score": "N/A"})
|
2022-11-19 12:05:26 +00:00
|
|
|
} else {
|
2022-11-20 12:30:12 +00:00
|
|
|
c.JSON(http.StatusOK, map[string]float64{"score": math.Round(*score*10) / 10})
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
2022-07-09 17:42:00 +00:00
|
|
|
} else {
|
|
|
|
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Not accessible"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
declareAPIAuthAsksRoutes(surveysRoutes)
|
|
|
|
declareAPIAuthDirectRoutes(surveysRoutes)
|
|
|
|
declareAPIAuthGradesRoutes(surveysRoutes)
|
|
|
|
declareAPIAuthQuestionsRoutes(surveysRoutes)
|
|
|
|
declareAPIAuthResponsesRoutes(surveysRoutes)
|
|
|
|
}
|
|
|
|
|
|
|
|
func declareAPIAdminSurveysRoutes(router *gin.RouterGroup) {
|
|
|
|
router.POST("/surveys", func(c *gin.Context) {
|
2020-03-04 11:07:12 +00:00
|
|
|
var new Survey
|
2022-07-09 17:42:00 +00:00
|
|
|
if err := c.ShouldBindJSON(&new); err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
|
2021-03-01 16:47:00 +00:00
|
|
|
if new.Promo == 0 {
|
|
|
|
new.Promo = currentPromo
|
|
|
|
}
|
|
|
|
|
2022-11-20 14:28:27 +00:00
|
|
|
if s, err := NewSurvey(new.IdCategory, new.Title, new.Promo, new.Group, new.Shown, new.Direct, new.StartAvailability, new.EndAvailability); err != nil {
|
2022-07-09 17:42:00 +00:00
|
|
|
log.Println("Unable to NewSurvey:", err)
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs during survey creation: %s", err.Error())})
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
c.JSON(http.StatusOK, s)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
surveysRoutes := router.Group("/surveys/:sid")
|
|
|
|
surveysRoutes.Use(surveyHandler)
|
|
|
|
|
|
|
|
surveysRoutes.PUT("", func(c *gin.Context) {
|
|
|
|
current := c.MustGet("survey").(*Survey)
|
|
|
|
|
2020-03-04 11:07:12 +00:00
|
|
|
var new Survey
|
2022-07-09 17:42:00 +00:00
|
|
|
if err := c.ShouldBindJSON(&new); err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
new.Id = current.Id
|
2022-02-28 18:00:30 +00:00
|
|
|
|
|
|
|
if new.Direct != current.Direct {
|
|
|
|
if new.Direct == nil {
|
|
|
|
current.WSCloseAll("")
|
|
|
|
} else if *new.Direct == 0 {
|
|
|
|
current.WSWriteAll(WSMessage{
|
|
|
|
Action: "pause",
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
current.WSWriteAll(WSMessage{
|
|
|
|
Action: "new_question",
|
|
|
|
QuestionId: new.Direct,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
if survey, err := new.Update(); err != nil {
|
|
|
|
log.Println("Unable to Update survey:", err)
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs during survey updation: %s", err.Error())})
|
|
|
|
return
|
2020-03-04 11:07:12 +00:00
|
|
|
} else {
|
2022-07-09 17:42:00 +00:00
|
|
|
c.JSON(http.StatusOK, survey)
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
2022-07-09 17:42:00 +00:00
|
|
|
})
|
|
|
|
surveysRoutes.DELETE("", func(c *gin.Context) {
|
|
|
|
survey := c.MustGet("survey").(*Survey)
|
2020-03-04 11:07:12 +00:00
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
if _, err := survey.Delete(); err != nil {
|
|
|
|
log.Println("Unable to Delete survey:", err)
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs during survey deletion: %s", err.Error())})
|
|
|
|
return
|
2020-03-04 11:07:12 +00:00
|
|
|
} else {
|
2022-07-09 17:42:00 +00:00
|
|
|
c.JSON(http.StatusOK, nil)
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
2022-07-09 17:42:00 +00:00
|
|
|
})
|
|
|
|
|
2022-12-02 10:48:10 +00:00
|
|
|
surveysRoutes.GET("shares", func(c *gin.Context) {
|
|
|
|
survey := c.MustGet("survey").(*Survey)
|
|
|
|
|
|
|
|
if sh, err := survey.getShares(); err != nil {
|
|
|
|
log.Println("Unable to getShares survey:", err)
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs during survey shares listing: %s", err.Error())})
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
c.JSON(http.StatusOK, sh)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
surveysRoutes.POST("shares", func(c *gin.Context) {
|
|
|
|
survey := c.MustGet("survey").(*Survey)
|
|
|
|
|
|
|
|
if sh, err := survey.Share(); err != nil {
|
|
|
|
log.Println("Unable to Share survey:", err)
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs during survey sharing: %s", err.Error())})
|
|
|
|
return
|
|
|
|
} else if url, err := sh.GetURL(); err != nil {
|
|
|
|
log.Println("Unable to GetURL share:", err)
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs during survey sharing: %s", err.Error())})
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
c.JSON(http.StatusOK, url.String())
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
declareAPIAdminAsksRoutes(surveysRoutes)
|
|
|
|
declareAPIAdminDirectRoutes(surveysRoutes)
|
|
|
|
declareAPIAdminQuestionsRoutes(surveysRoutes)
|
|
|
|
}
|
|
|
|
|
|
|
|
func surveyHandler(c *gin.Context) {
|
|
|
|
if sid, err := strconv.Atoi(string(c.Param("sid"))); err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Bad survey identifier."})
|
|
|
|
return
|
|
|
|
} else if survey, err := getSurvey(sid); err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Survey not found."})
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
c.Set("survey", survey)
|
|
|
|
c.Next()
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-19 10:41:35 +00:00
|
|
|
func (s *Survey) checkUserAccessToSurvey(u *User) bool {
|
|
|
|
return u.IsAdmin || (u.Promo == s.Promo && s.Shown && (s.Group == "" || strings.Contains(u.Groups, ","+s.Group+",")))
|
|
|
|
}
|
|
|
|
|
2022-09-07 19:33:54 +00:00
|
|
|
func surveyUserAccessHandler(c *gin.Context) {
|
|
|
|
u := c.MustGet("LoggedUser").(*User)
|
2022-11-19 10:41:35 +00:00
|
|
|
s := c.MustGet("survey").(*Survey)
|
2022-09-07 19:33:54 +00:00
|
|
|
|
2022-11-19 10:41:35 +00:00
|
|
|
if !s.checkUserAccessToSurvey(u) {
|
2022-09-07 19:33:54 +00:00
|
|
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Survey not found."})
|
|
|
|
return
|
|
|
|
}
|
2022-11-19 10:41:35 +00:00
|
|
|
|
|
|
|
c.Next()
|
2022-09-07 19:33:54 +00:00
|
|
|
}
|
|
|
|
|
2020-03-04 11:07:12 +00:00
|
|
|
type Survey struct {
|
|
|
|
Id int64 `json:"id"`
|
2022-11-20 14:28:27 +00:00
|
|
|
IdCategory int64 `json:"id_category"`
|
2020-03-04 11:07:12 +00:00
|
|
|
Title string `json:"title"`
|
2021-03-01 16:47:00 +00:00
|
|
|
Promo uint `json:"promo"`
|
2022-02-21 07:53:27 +00:00
|
|
|
Group string `json:"group"`
|
2020-03-04 11:07:12 +00:00
|
|
|
Shown bool `json:"shown"`
|
2022-02-28 18:00:30 +00:00
|
|
|
Direct *int64 `json:"direct"`
|
2020-03-08 00:06:44 +00:00
|
|
|
Corrected bool `json:"corrected"`
|
2020-03-04 11:07:12 +00:00
|
|
|
StartAvailability time.Time `json:"start_availability"`
|
|
|
|
EndAvailability time.Time `json:"end_availability"`
|
|
|
|
}
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
func getSurveys(cnd string, param ...interface{}) (surveys []*Survey, err error) {
|
2022-11-20 14:28:27 +00:00
|
|
|
if rows, errr := DBQuery("SELECT id_survey, id_category, title, promo, grp, shown, direct, corrected, start_availability, end_availability FROM surveys "+cnd, param...); errr != nil {
|
2020-03-04 11:07:12 +00:00
|
|
|
return nil, errr
|
|
|
|
} else {
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
var s Survey
|
2022-11-20 14:28:27 +00:00
|
|
|
if err = rows.Scan(&s.Id, &s.IdCategory, &s.Title, &s.Promo, &s.Group, &s.Shown, &s.Direct, &s.Corrected, &s.StartAvailability, &s.EndAvailability); err != nil {
|
2020-03-04 11:07:12 +00:00
|
|
|
return
|
|
|
|
}
|
2022-07-09 17:42:00 +00:00
|
|
|
surveys = append(surveys, &s)
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
if err = rows.Err(); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
func getSurvey(id int) (s *Survey, err error) {
|
2022-09-02 12:08:03 +00:00
|
|
|
_surveys_cache_mutex.RLock()
|
|
|
|
survey, ok := _surveys_cache[int64(id)]
|
|
|
|
_surveys_cache_mutex.RUnlock()
|
|
|
|
if ok {
|
|
|
|
return survey, nil
|
|
|
|
}
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
s = new(Survey)
|
2022-11-20 14:28:27 +00:00
|
|
|
err = DBQueryRow("SELECT id_survey, id_category, title, promo, grp, shown, direct, corrected, start_availability, end_availability FROM surveys WHERE id_survey=?", id).Scan(&s.Id, &s.IdCategory, &s.Title, &s.Promo, &s.Group, &s.Shown, &s.Direct, &s.Corrected, &s.StartAvailability, &s.EndAvailability)
|
2022-09-02 12:08:03 +00:00
|
|
|
|
|
|
|
_surveys_cache_mutex.Lock()
|
|
|
|
_surveys_cache[int64(id)] = s
|
|
|
|
_surveys_cache_mutex.Unlock()
|
2020-03-04 11:07:12 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-11-20 14:28:27 +00:00
|
|
|
func NewSurvey(id_category int64, title string, promo uint, group string, shown bool, direct *int64, startAvailability time.Time, endAvailability time.Time) (*Survey, error) {
|
|
|
|
if res, err := DBExec("INSERT INTO surveys (id_category, title, promo, grp, shown, direct, start_availability, end_availability) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", id_category, title, promo, group, shown, direct, startAvailability, endAvailability); err != nil {
|
2022-02-21 06:13:39 +00:00
|
|
|
return nil, err
|
2020-03-04 11:07:12 +00:00
|
|
|
} else if sid, err := res.LastInsertId(); err != nil {
|
2022-02-21 06:13:39 +00:00
|
|
|
return nil, err
|
2020-03-04 11:07:12 +00:00
|
|
|
} else {
|
2022-11-20 14:28:27 +00:00
|
|
|
return &Survey{sid, id_category, title, promo, group, shown, direct, false, startAvailability, endAvailability}, nil
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-13 14:37:30 +00:00
|
|
|
func (s Survey) GetScore(u *User) (score *float64, err error) {
|
2022-09-02 12:08:03 +00:00
|
|
|
_score_cache_mutex.RLock()
|
2022-02-28 16:45:30 +00:00
|
|
|
if _, ok := _score_cache[u.Id]; !ok {
|
2022-09-02 12:08:03 +00:00
|
|
|
_score_cache_mutex.RUnlock()
|
|
|
|
_score_cache_mutex.Lock()
|
2022-02-28 16:45:30 +00:00
|
|
|
_score_cache[u.Id] = map[int64]*float64{}
|
2022-09-02 12:08:03 +00:00
|
|
|
_score_cache_mutex.Unlock()
|
|
|
|
_score_cache_mutex.RLock()
|
2022-02-28 16:45:30 +00:00
|
|
|
}
|
2022-09-02 12:08:03 +00:00
|
|
|
|
|
|
|
v, ok := _score_cache[u.Id][s.Id]
|
|
|
|
_score_cache_mutex.RUnlock()
|
|
|
|
|
|
|
|
if ok {
|
2022-02-28 16:45:30 +00:00
|
|
|
score = v
|
|
|
|
} else {
|
2023-03-08 03:40:03 +00:00
|
|
|
err = DBQueryRow("SELECT SUM(score)/COUNT(*) FROM student_scores WHERE kind = 'survey' AND id=? AND id_user=?", s.Id, u.Id).Scan(&score)
|
2022-02-28 16:45:30 +00:00
|
|
|
if score != nil {
|
|
|
|
*score = *score / 5.0
|
|
|
|
}
|
2022-09-02 12:08:03 +00:00
|
|
|
|
|
|
|
_score_cache_mutex.Lock()
|
2022-02-28 16:45:30 +00:00
|
|
|
_score_cache[u.Id][s.Id] = score
|
2022-09-02 12:08:03 +00:00
|
|
|
_score_cache_mutex.Unlock()
|
2020-09-13 14:37:30 +00:00
|
|
|
}
|
2020-11-20 14:46:52 +00:00
|
|
|
return
|
|
|
|
}
|
2020-09-13 14:37:30 +00:00
|
|
|
|
2020-11-20 14:46:52 +00:00
|
|
|
func (s Survey) GetScores() (scores map[int64]*float64, err error) {
|
2023-03-08 03:40:03 +00:00
|
|
|
if rows, errr := DBQuery("SELECT id_user, SUM(score)/COUNT(*) FROM student_scores WHERE kind = 'survey' AND id_survey=? GROUP BY id_user", s.Id); errr != nil {
|
2020-11-20 14:46:52 +00:00
|
|
|
return nil, errr
|
|
|
|
} else {
|
|
|
|
defer rows.Close()
|
2020-09-13 14:37:30 +00:00
|
|
|
|
2020-11-20 14:46:52 +00:00
|
|
|
scores = map[int64]*float64{}
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
var id_user int64
|
|
|
|
var score *float64
|
|
|
|
|
|
|
|
if err = rows.Scan(&id_user, &score); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
scores[id_user] = score
|
|
|
|
}
|
|
|
|
if err = rows.Err(); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2020-09-13 14:37:30 +00:00
|
|
|
|
2020-03-08 00:06:44 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-02-21 06:13:39 +00:00
|
|
|
func (s *Survey) Update() (*Survey, error) {
|
2022-11-20 14:28:27 +00:00
|
|
|
if _, err := DBExec("UPDATE surveys SET id_category = ?, title = ?, promo = ?, grp = ?, shown = ?, direct = ?, corrected = ?, start_availability = ?, end_availability = ? WHERE id_survey = ?", s.IdCategory, s.Title, s.Promo, s.Group, s.Shown, s.Direct, s.Corrected, s.StartAvailability, s.EndAvailability, s.Id); err != nil {
|
2022-02-21 06:13:39 +00:00
|
|
|
return nil, err
|
2020-03-04 11:07:12 +00:00
|
|
|
} else {
|
2022-09-02 12:08:03 +00:00
|
|
|
_surveys_cache_mutex.Lock()
|
|
|
|
_surveys_cache[s.Id] = s
|
|
|
|
_surveys_cache_mutex.Unlock()
|
2022-02-21 06:13:39 +00:00
|
|
|
return s, err
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s Survey) Delete() (int64, error) {
|
2022-12-02 10:48:10 +00:00
|
|
|
DBExec("DELETE FROM survey_shared WHERE id_survey = ?", s.Id)
|
2020-03-04 11:07:12 +00:00
|
|
|
if res, err := DBExec("DELETE FROM surveys WHERE id_survey = ?", s.Id); err != nil {
|
|
|
|
return 0, err
|
|
|
|
} else if nb, err := res.RowsAffected(); err != nil {
|
|
|
|
return 0, err
|
|
|
|
} else {
|
2022-09-02 12:08:03 +00:00
|
|
|
_surveys_cache_mutex.Lock()
|
|
|
|
delete(_surveys_cache, s.Id)
|
|
|
|
_surveys_cache_mutex.Unlock()
|
2020-03-04 11:07:12 +00:00
|
|
|
return nb, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func ClearSurveys() (int64, error) {
|
|
|
|
if res, err := DBExec("DELETE FROM surveys"); err != nil {
|
|
|
|
return 0, err
|
|
|
|
} else if nb, err := res.RowsAffected(); err != nil {
|
|
|
|
return 0, err
|
|
|
|
} else {
|
2022-09-02 12:08:03 +00:00
|
|
|
_surveys_cache_mutex.Lock()
|
|
|
|
_surveys_cache = map[int64]*Survey{}
|
|
|
|
_surveys_cache_mutex.Unlock()
|
2020-03-04 11:07:12 +00:00
|
|
|
return nb, err
|
|
|
|
}
|
|
|
|
}
|