Newer
Older
package model
import (
"code.electrolab.fr/it/vote.electrolab.fr/service/db"
"context"
"fmt"
)
type Question struct {
Name string
Position int
Title string
Sentence string
MinChoices int
MaxChoices int
VoteOpen bool
VoteCount int
VotedAlready bool // computed field if requesterUuid is provided
Answers []*Answer // might not be populated
func FetchQuestions(ctx context.Context, db db.Service, requesterUuid string) ([]*Question, error) {
return fetchQuestions(ctx, db, requesterUuid, "")
}
func FetchQuestion(ctx context.Context, db db.Service, requesterUuid, questionName string) (*Question, error) {
if len(questionName) == 0 {
return nil, fmt.Errorf("Question name not provided")
}
result, err := fetchQuestions(ctx, db, requesterUuid, questionName)
if err != nil {
return nil, err
}
if len(result) == 0 {
return nil, nil
return nil, fmt.Errorf("Invalid number of questions returned: %d", len(result))
}
question := result[0]
question.Answers, err = FetchAnswers(ctx, db, questionName)
if err != nil {
return nil, err
}
return question, nil
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
}
func fetchQuestions(ctx context.Context, db db.Service, requesterUuid, questionName string) ([]*Question, error) {
var (
err error
args []interface{}
)
q := `
SELECT
name,
position,
title,
sentence,
min_choices,
COALESCE(max_choices, -1),
vote_open,
vote_count,
`
if len(requesterUuid) > 0 {
args = append(args, requesterUuid)
q += fmt.Sprintf(` COALESCE((SELECT TRUE FROM votes WHERE votes.question_name=questions.name AND user_uuid=$%d), FALSE) as voted_already `, len(args))
} else {
q += ` FALSE as voted_already `
}
q += ` FROM questions `
if len(questionName) > 0 {
args = append(args, questionName)
q += fmt.Sprintf(` WHERE name = $%d `, len(args))
}
q += ` ORDER BY position `
var result []*Question
rows, err := db.QueryContext(ctx, q, args...)
if err != nil {
return nil, fmt.Errorf("Error fetching question: %w", err)
}
defer rows.Close()
for rows.Next() {
question := new(Question)
err = rows.Scan(
&question.Name,
&question.Position,
&question.Title,
&question.Sentence,
&question.MinChoices,
&question.MaxChoices,
&question.VoteOpen,
&question.VoteCount,
&question.VotedAlready,
)
if err != nil {
return nil, fmt.Errorf("Error fetching questions: %w", err)
}
result = append(result, question)
}
return result, nil
}