147 lines
3.1 KiB
Go
147 lines
3.1 KiB
Go
package memory
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"git.andreafazzi.eu/andrea/probo/client"
|
|
"git.andreafazzi.eu/andrea/probo/hasher"
|
|
"git.andreafazzi.eu/andrea/probo/models"
|
|
)
|
|
|
|
type MemoryQuizHubCollectorStore struct {
|
|
questions map[string]*models.Question
|
|
answers map[string]*models.Answer
|
|
quizzes map[string]*models.Quiz
|
|
|
|
questionAnswer map[string][]string
|
|
testQuestion map[string]uint
|
|
|
|
// A mutex is used to synchronize read/write access to the map
|
|
lock sync.RWMutex
|
|
|
|
hasher hasher.Hasher
|
|
}
|
|
|
|
func NewMemoryQuizHubCollectorStore(hasher hasher.Hasher) *MemoryQuizHubCollectorStore {
|
|
s := new(MemoryQuizHubCollectorStore)
|
|
|
|
s.hasher = hasher
|
|
s.questions = make(map[string]*models.Question)
|
|
s.answers = make(map[string]*models.Answer)
|
|
s.quizzes = make(map[string]*models.Quiz)
|
|
|
|
return s
|
|
}
|
|
|
|
func (s *MemoryQuizHubCollectorStore) readQuiz(id string) *models.Quiz {
|
|
s.lock.RLock()
|
|
defer s.lock.RUnlock()
|
|
|
|
quiz, ok := s.quizzes[id]
|
|
if ok {
|
|
return quiz
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *MemoryQuizHubCollectorStore) readQuestion(id string) *models.Question {
|
|
s.lock.RLock()
|
|
defer s.lock.RUnlock()
|
|
|
|
question, ok := s.questions[id]
|
|
if ok {
|
|
return question
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *MemoryQuizHubCollectorStore) readAnswer(id string) *models.Answer {
|
|
s.lock.RLock()
|
|
defer s.lock.RUnlock()
|
|
|
|
answer, ok := s.answers[id]
|
|
if ok {
|
|
return answer
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *MemoryQuizHubCollectorStore) createQuiz(id string, quiz *models.Quiz) *models.Quiz {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
|
|
quiz.ID = id
|
|
s.quizzes[id] = quiz
|
|
|
|
return quiz
|
|
}
|
|
|
|
func (s *MemoryQuizHubCollectorStore) createQuestion(id string, question *models.Question) *models.Question {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
|
|
s.questions[id] = question
|
|
|
|
return question
|
|
}
|
|
|
|
func (s *MemoryQuizHubCollectorStore) createAnswer(id string, answer *models.Answer) *models.Answer {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
|
|
s.answers[id] = answer
|
|
|
|
return answer
|
|
}
|
|
|
|
func (s *MemoryQuizHubCollectorStore) ReadAllQuizzes() ([]*models.Quiz, error) {
|
|
result := make([]*models.Quiz, 0)
|
|
for id, _ := range s.quizzes {
|
|
result = append(result, s.readQuiz(id))
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (s *MemoryQuizHubCollectorStore) CreateQuiz(r *client.CreateQuizRequest) (*models.Quiz, error) {
|
|
hashes := s.hasher.QuizHashes(r)
|
|
|
|
quizID := hashes[len(hashes)-1]
|
|
|
|
quiz := s.readQuiz(quizID)
|
|
if quiz != nil { // Quiz is already present in the store
|
|
return quiz, nil
|
|
}
|
|
|
|
quiz = new(models.Quiz)
|
|
|
|
questionID := hashes[0]
|
|
q := s.readQuestion(questionID)
|
|
if q == nil { // if the question is not in the store add it
|
|
q = s.createQuestion(questionID, &models.Question{
|
|
ID: questionID,
|
|
Text: r.Question.Text,
|
|
})
|
|
}
|
|
|
|
// Populate Question field
|
|
quiz.Question = q
|
|
for i, answer := range r.Answers {
|
|
answerID := hashes[i+1]
|
|
a := s.readAnswer(answerID)
|
|
if a == nil { // if the answer is not in the store add it
|
|
a = s.createAnswer(answerID, &models.Answer{
|
|
ID: answerID,
|
|
Text: answer.Text,
|
|
})
|
|
if answer.Correct {
|
|
quiz.Correct = a // s.readAnswer(answerID)
|
|
}
|
|
}
|
|
quiz.Answers = append(quiz.Answers, a)
|
|
}
|
|
|
|
return s.createQuiz(quizID, quiz), nil
|
|
}
|