Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
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
}
func FetchAllQuestions(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
} else if len(result) == 1 {
return result[0], nil
} else {
return nil, fmt.Errorf("Invalid number of questions returned: %d", len(result))
}
}
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
}