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 } else if len(result) != 1 { 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 } 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 }