package memory import ( "sync" "git.andreafazzi.eu/andrea/probo/client" "git.andreafazzi.eu/andrea/probo/hasher" "git.andreafazzi.eu/andrea/probo/models" "github.com/google/uuid" ) 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, hash string, quiz *models.Quiz) *models.Quiz { s.lock.Lock() defer s.lock.Unlock() quiz.ID = id s.quizzes[hash] = 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.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) 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 }