diff --git a/pkg/training/error.go b/pkg/training/error.go index a9bdc11..aedd058 100644 --- a/pkg/training/error.go +++ b/pkg/training/error.go @@ -3,6 +3,7 @@ package training import "errors" var ( - ErrTrainingNotFound = errors.New("training not found") - ErrTrainingDateNotFound = errors.New("training date not found") + ErrTrainingNotFound = errors.New("training not found") + ErrTrainingDateNotFound = errors.New("training date not found") + ErrTrainingDateAttendeeNotFound = errors.New("training date attendee not found") ) diff --git a/pkg/training/repository.go b/pkg/training/repository.go index 8a1edc9..81fa595 100644 --- a/pkg/training/repository.go +++ b/pkg/training/repository.go @@ -193,3 +193,105 @@ func (r *InMemoryTrainingDateRepository) Delete(id TrainingDateID) error { return nil } + +type TrainingDateAttendeeRepository interface { + Create(trainingDateID TrainingDateID, attendee *TrainingDateAttendee) error + FindByID(id TrainingDateAttendeeID) (*TrainingDateAttendee, error) + FindAll() ([]TrainingDateAttendee, error) + FindAllByTrainingDateID(trainingDateID TrainingDateID) ([]TrainingDateAttendee, error) + Update(attendee *TrainingDateAttendee) error + Delete(id TrainingDateAttendeeID) error +} + +type InMemoryTrainingDateAttendeeRepository struct { + attendees map[TrainingDateAttendeeID]TrainingDateAttendee + dateToAttendees map[TrainingDateID][]TrainingDateAttendeeID + + lock sync.RWMutex +} + +func NewInMemoryTrainingDateAttendeeRepository() *InMemoryTrainingDateAttendeeRepository { + return &InMemoryTrainingDateAttendeeRepository{ + attendees: make(map[TrainingDateAttendeeID]TrainingDateAttendee), + dateToAttendees: make(map[TrainingDateID][]TrainingDateAttendeeID), + } +} + +func (r *InMemoryTrainingDateAttendeeRepository) Create(trainingDateID TrainingDateID, attendee *TrainingDateAttendee) error { + r.lock.Lock() + defer r.lock.Unlock() + + attendee.ID = NewTrainingDateAttendeeID() + attendee.trainingDateID = trainingDateID + + r.attendees[attendee.ID] = *attendee + r.dateToAttendees[trainingDateID] = append(r.dateToAttendees[trainingDateID], attendee.ID) + + return nil +} + +func (r *InMemoryTrainingDateAttendeeRepository) FindByID(id TrainingDateAttendeeID) (*TrainingDateAttendee, error) { + r.lock.RLock() + defer r.lock.RUnlock() + + attendee, ok := r.attendees[id] + if !ok { + return nil, ErrTrainingDateAttendeeNotFound + } + return &attendee, nil +} + +func (r *InMemoryTrainingDateAttendeeRepository) FindAll() ([]TrainingDateAttendee, error) { + r.lock.RLock() + defer r.lock.RUnlock() + + attendees := make([]TrainingDateAttendee, len(r.attendees)) + for _, attendee := range r.attendees { + attendees = append(attendees, attendee) + } + + return attendees, nil +} + +func (r *InMemoryTrainingDateAttendeeRepository) FindAllByTrainingDateID(trainingDateID TrainingDateID) ([]TrainingDateAttendee, error) { + r.lock.RLock() + defer r.lock.RUnlock() + + attendees := make([]TrainingDateAttendee, 0) + for _, id := range r.dateToAttendees[trainingDateID] { + attendees = append(attendees, r.attendees[id]) + } + + return attendees, nil +} + +func (r *InMemoryTrainingDateAttendeeRepository) Update(attendee *TrainingDateAttendee) error { + r.lock.Lock() + defer r.lock.Unlock() + + oldAttendee := r.attendees[attendee.ID] + attendee.trainingDateID = oldAttendee.trainingDateID + r.attendees[attendee.ID] = *attendee + return nil +} + +func (r *InMemoryTrainingDateAttendeeRepository) Delete(id TrainingDateAttendeeID) error { + r.lock.Lock() + defer r.lock.Unlock() + + attendee, ok := r.attendees[id] + if !ok { + return ErrTrainingDateAttendeeNotFound + } + + delete(r.attendees, id) + attendees := r.dateToAttendees[attendee.trainingDateID] + for idx, a := range attendees { + if a == id { + r.dateToAttendees[attendee.trainingDateID] = append(attendees[:idx], attendees[idx+1:]...) + break + } + } + + return nil +}