123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- package store
- import (
- "fmt"
- "strings"
- "git.andreafazzi.eu/andrea/probo/models"
- )
- type ErrQuizAlreadyPresent struct {
- hash string
- }
- func (e *ErrQuizAlreadyPresent) Error() string {
- return fmt.Sprintf("Quiz with hash %v is already present in the store.", e.hash)
- }
- type QuizStore struct {
- // Memory store for quizzes. It satisfies FilterStorer
- // interface.
- *FilterStore[*models.Quiz]
- questions *Store[*models.Question]
- answers *Store[*models.Answer]
- }
- func NewQuizStore() *QuizStore {
- store := new(QuizStore)
- store.questions = NewStore[*models.Question]()
- store.answers = NewStore[*models.Answer]()
- store.FilterStore = NewFilterStore[*models.Quiz]()
- return store
- }
- func (s *QuizStore) Create(quiz *models.Quiz) (*models.Quiz, error) {
- if hash := quiz.GetHash(); hash != "" {
- q, ok := s.hashes[hash]
- if ok {
- return q, &ErrQuizAlreadyPresent{hash}
- }
- }
- question, err := s.questions.Create(quiz.Question)
- if err != nil {
- return nil, err
- }
- answers := make([]*models.Answer, 0)
- for _, a := range quiz.Answers {
- storedAnswer, err := s.answers.Create(a)
- if err != nil {
- return nil, err
- }
- answers = append(answers, storedAnswer)
- }
- tags := make([]*models.Tag, 0)
- q, err := s.Store.Create(&models.Quiz{
- Meta: quiz.Meta,
- Question: parseTags[*models.Question](&tags, question)[0],
- Answers: parseTags[*models.Answer](&tags, answers...),
- Correct: answers[quiz.CorrectPos],
- CorrectPos: quiz.CorrectPos,
- Tags: tags,
- })
- if err != nil {
- return nil, err
- }
- return q, nil
- }
- func (s *QuizStore) Update(quiz *models.Quiz, id string) (*models.Quiz, error) {
- _, err := s.Read(id)
- if err != nil {
- return quiz, err
- }
- question, err := s.questions.Create(quiz.Question)
- if err != nil {
- return nil, err
- }
- answers := make([]*models.Answer, 0)
- for _, a := range quiz.Answers {
- storedAnswer, err := s.answers.Create(a)
- if err != nil {
- return nil, err
- }
- answers = append(answers, storedAnswer)
- }
- tags := make([]*models.Tag, 0)
- q, err := s.Store.Update(&models.Quiz{
- Question: parseTags[*models.Question](&tags, question)[0],
- Answers: parseTags[*models.Answer](&tags, answers...),
- Correct: answers[quiz.CorrectPos],
- CorrectPos: quiz.CorrectPos,
- Tags: tags,
- }, id)
- if err != nil {
- return nil, err
- }
- return q, nil
- }
- func (s *QuizStore) FilterInCollection(collection *models.Collection, filter *models.Filter) []*models.Quiz {
- quizzes := s.ReadAll()
- filteredQuizzes := s.Filter(quizzes, func(q *models.Quiz) bool {
- count := 0
- for _, qTag := range q.Tags {
- if s.isTagInFilter(qTag, filter) {
- count++
- }
- }
- if count == len(filter.Tags) {
- return true
- }
- return false
- })
- collection.Quizzes = filteredQuizzes
- return collection.Quizzes
- }
- func (s *QuizStore) isTagInFilter(tag *models.Tag, filter *models.Filter) bool {
- for _, fTag := range filter.Tags {
- if tag.Name == fTag.Name {
- return true
- }
- }
- return false
- }
- func parseTags[T fmt.Stringer](tags *[]*models.Tag, entities ...T) []T {
- for _, entity := range entities {
- // Trim the following chars
- trimChars := "*:.,/\\@()[]{}<>"
- // Split the text into words
- words := strings.Fields(entity.String())
- for _, word := range words {
- // If the word starts with '#', it is considered as a tag
- if strings.HasPrefix(word, "#") {
- // Check if the tag already exists in the tags slice
- exists := false
- for _, tag := range *tags {
- if tag.Name == word {
- exists = true
- break
- }
- }
- // If the tag does not exist in the tags slice, add it
- if !exists {
- *tags = append(*tags, &models.Tag{Name: strings.TrimRight(word, trimChars)})
- }
- }
- }
- }
- return entities
- }
|