279 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			279 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package training
 | |
| 
 | |
| import (
 | |
| 	"sync"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| type InMemoryTrainingRepository struct {
 | |
| 	trainings map[ID]Training
 | |
| 	lock      sync.RWMutex
 | |
| 	ai        int
 | |
| }
 | |
| 
 | |
| func NewInMemoryTrainingRepository() *InMemoryTrainingRepository {
 | |
| 	return &InMemoryTrainingRepository{
 | |
| 		trainings: make(map[ID]Training),
 | |
| 		ai:        1,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingRepository) Create(training *Training) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	training.ID = r.ai
 | |
| 	r.ai++
 | |
| 	r.trainings[training.ID] = *training
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingRepository) FindByID(id ID) (*Training, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	training, ok := r.trainings[id]
 | |
| 	if !ok {
 | |
| 		return nil, ErrTrainingNotFound
 | |
| 	}
 | |
| 	return &training, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingRepository) FindAll() ([]Training, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	trainings := make([]Training, 0, len(r.trainings))
 | |
| 	for _, training := range r.trainings {
 | |
| 		trainings = append(trainings, training)
 | |
| 	}
 | |
| 	return trainings, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingRepository) Update(training *Training) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	r.trainings[training.ID] = *training
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingRepository) Delete(id ID) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	_, ok := r.trainings[id]
 | |
| 	if !ok {
 | |
| 		return ErrTrainingNotFound
 | |
| 	}
 | |
| 
 | |
| 	delete(r.trainings, id)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| type InMemoryDateRepository struct {
 | |
| 	trainingDates   map[DateID]Date
 | |
| 	trainingToDates map[ID][]DateID
 | |
| 
 | |
| 	lock sync.RWMutex
 | |
| 	ai   int
 | |
| }
 | |
| 
 | |
| func NewInMemoryDateRepository() *InMemoryDateRepository {
 | |
| 	return &InMemoryDateRepository{
 | |
| 		trainingDates:   make(map[DateID]Date),
 | |
| 		trainingToDates: make(map[ID][]DateID),
 | |
| 		ai:              1,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (r *InMemoryDateRepository) Create(trainingID ID, trainingDate *Date) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	trainingDate.ID = r.ai
 | |
| 	r.ai++
 | |
| 	trainingDate.trainingID = trainingID
 | |
| 
 | |
| 	r.trainingDates[trainingDate.ID] = *trainingDate
 | |
| 	r.trainingToDates[trainingID] = append(r.trainingToDates[trainingID], trainingDate.ID)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryDateRepository) FindByID(id DateID) (*Date, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	date, ok := r.trainingDates[id]
 | |
| 	if !ok {
 | |
| 		return nil, ErrTrainingDateNotFound
 | |
| 	}
 | |
| 	return &date, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryDateRepository) FindAll() ([]Date, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	dates := make([]Date, len(r.trainingDates))
 | |
| 	for _, date := range r.trainingDates {
 | |
| 		dates = append(dates, date)
 | |
| 	}
 | |
| 
 | |
| 	return dates, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryDateRepository) FindAllByTrainingID(trainingID ID) ([]Date, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	dates := make([]Date, 0)
 | |
| 	for _, id := range r.trainingToDates[trainingID] {
 | |
| 		dates = append(dates, r.trainingDates[id])
 | |
| 	}
 | |
| 
 | |
| 	return dates, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryDateRepository) FindUpcomingByTrainingID(trainingID ID) ([]Date, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	now := time.Now()
 | |
| 	var dates []Date
 | |
| 	for _, id := range r.trainingToDates[trainingID] {
 | |
| 		date := r.trainingDates[id]
 | |
| 		if date.Date.After(now) {
 | |
| 			dates = append(dates, date)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return dates, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryDateRepository) Update(trainingDate *Date) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	oldDate := r.trainingDates[trainingDate.ID]
 | |
| 	trainingDate.trainingID = oldDate.trainingID
 | |
| 	r.trainingDates[trainingDate.ID] = *trainingDate
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryDateRepository) Delete(id DateID) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	date, ok := r.trainingDates[id]
 | |
| 	if !ok {
 | |
| 		return ErrTrainingDateNotFound
 | |
| 	}
 | |
| 
 | |
| 	delete(r.trainingDates, id)
 | |
| 	dates := r.trainingToDates[date.trainingID]
 | |
| 	for idx, d := range dates {
 | |
| 		if d == id {
 | |
| 			r.trainingToDates[date.trainingID] = append(dates[:idx], dates[idx+1:]...)
 | |
| 			break
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| type InMemoryAttendeeRepository struct {
 | |
| 	attendees       map[AttendeeID]Attendee
 | |
| 	dateToAttendees map[DateID][]AttendeeID
 | |
| 
 | |
| 	lock sync.RWMutex
 | |
| 	ai   int
 | |
| }
 | |
| 
 | |
| func NewInMemoryAttendeeRepository() *InMemoryAttendeeRepository {
 | |
| 	return &InMemoryAttendeeRepository{
 | |
| 		attendees:       make(map[AttendeeID]Attendee),
 | |
| 		dateToAttendees: make(map[DateID][]AttendeeID),
 | |
| 		ai:              1,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (r *InMemoryAttendeeRepository) Create(trainingDateID DateID, attendee *Attendee) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	attendee.ID = r.ai
 | |
| 	r.ai++
 | |
| 	attendee.trainingDateID = trainingDateID
 | |
| 
 | |
| 	r.attendees[attendee.ID] = *attendee
 | |
| 	r.dateToAttendees[trainingDateID] = append(r.dateToAttendees[trainingDateID], attendee.ID)
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryAttendeeRepository) FindByID(id AttendeeID) (*Attendee, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	attendee, ok := r.attendees[id]
 | |
| 	if !ok {
 | |
| 		return nil, ErrTrainingDateAttendeeNotFound
 | |
| 	}
 | |
| 	return &attendee, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryAttendeeRepository) FindAll() ([]Attendee, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	attendees := make([]Attendee, len(r.attendees))
 | |
| 	for _, attendee := range r.attendees {
 | |
| 		attendees = append(attendees, attendee)
 | |
| 	}
 | |
| 
 | |
| 	return attendees, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryAttendeeRepository) FindAllByTrainingDateID(trainingDateID DateID) ([]Attendee, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	attendees := make([]Attendee, 0)
 | |
| 	for _, id := range r.dateToAttendees[trainingDateID] {
 | |
| 		attendees = append(attendees, r.attendees[id])
 | |
| 	}
 | |
| 
 | |
| 	return attendees, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryAttendeeRepository) Update(attendee *Attendee) 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 *InMemoryAttendeeRepository) Delete(id AttendeeID) 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
 | |
| }
 |