probo/store/memory/memory.go

192 lines
4.3 KiB
Go
Raw Normal View History

2022-06-24 18:56:06 +02:00
package memory
import (
"sync"
"git.andreafazzi.eu/andrea/probo/client"
"git.andreafazzi.eu/andrea/probo/hasher"
"git.andreafazzi.eu/andrea/probo/models"
2022-06-27 15:11:37 +02:00
"github.com/google/uuid"
2022-06-24 18:56:06 +02:00
)
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
}
2022-06-27 15:11:37 +02:00
func (s *MemoryQuizHubCollectorStore) createQuiz(id string, hash string, quiz *models.Quiz) *models.Quiz {
2022-06-24 18:56:06 +02:00
s.lock.Lock()
defer s.lock.Unlock()
quiz.ID = id
2022-06-27 15:11:37 +02:00
s.quizzes[hash] = quiz
2022-06-24 18:56:06 +02:00
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) {
2022-06-28 13:49:35 +02:00
hashes := s.hasher.QuizHashes(r.Quiz)
quizID := uuid.New().String()
quizHash := hashes[len(hashes)-1]
quiz := s.readQuiz(quizHash)
if quiz != nil { // Quiz is already present in the store
return quiz, nil
}
quiz = new(models.Quiz)
questionHash := hashes[0]
q := s.readQuestion(questionHash)
if q == nil { // if the question is not in the store then we should add it
q = s.createQuestion(questionHash, &models.Question{
ID: uuid.New().String(),
Text: r.Question.Text,
})
}
// Populate Question field
quiz.Question = q
for i, answer := range r.Answers {
answerHash := hashes[i+1]
a := s.readAnswer(answerHash)
if a == nil { // if the answer is not in the store add it
a = s.createAnswer(answerHash, &models.Answer{
ID: uuid.New().String(),
Text: answer.Text,
})
if answer.Correct {
quiz.Correct = a // s.readAnswer(answerID)
}
}
quiz.Answers = append(quiz.Answers, a)
}
return s.createQuiz(quizID, quizHash, quiz), nil
}
func (s *MemoryQuizHubCollectorStore) UpdateQuiz(r *client.UpdateQuizRequest) (*models.Quiz, error) {
hashes := s.hasher.QuizHashes(r.Quiz)
2022-06-24 18:56:06 +02:00
2022-06-27 15:11:37 +02:00
quizID := uuid.New().String()
quizHash := hashes[len(hashes)-1]
2022-06-24 18:56:06 +02:00
2022-06-27 15:11:37 +02:00
quiz := s.readQuiz(quizHash)
2022-06-24 18:56:06 +02:00
if quiz != nil { // Quiz is already present in the store
return quiz, nil
}
quiz = new(models.Quiz)
2022-06-27 15:11:37 +02:00
questionHash := hashes[0]
q := s.readQuestion(questionHash)
if q == nil { // if the question is not in the store then we should add it
q = s.createQuestion(questionHash, &models.Question{
ID: uuid.New().String(),
2022-06-24 18:56:06 +02:00
Text: r.Question.Text,
})
}
// Populate Question field
quiz.Question = q
for i, answer := range r.Answers {
2022-06-27 15:11:37 +02:00
answerHash := hashes[i+1]
a := s.readAnswer(answerHash)
2022-06-24 18:56:06 +02:00
if a == nil { // if the answer is not in the store add it
2022-06-27 15:11:37 +02:00
a = s.createAnswer(answerHash, &models.Answer{
ID: uuid.New().String(),
2022-06-24 18:56:06 +02:00
Text: answer.Text,
})
if answer.Correct {
quiz.Correct = a // s.readAnswer(answerID)
}
}
quiz.Answers = append(quiz.Answers, a)
}
2022-06-27 15:11:37 +02:00
return s.createQuiz(quizID, quizHash, quiz), nil
2022-06-24 18:56:06 +02:00
}