345 lines
		
	
	
	
		
			7.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			345 lines
		
	
	
	
		
			7.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package training
 | |
| 
 | |
| import (
 | |
| 	"sync"
 | |
| 
 | |
| 	"github.com/shopspring/decimal"
 | |
| 	"gitlab.mareshq.com/hq/yggdrasil/internal/currency"
 | |
| )
 | |
| 
 | |
| type TrainingRepository interface {
 | |
| 	Create(training *Training) error
 | |
| 	FindByID(id TrainingID) (*Training, error)
 | |
| 	FindAll() ([]Training, error)
 | |
| 	Update(training *Training) error
 | |
| 	Delete(id TrainingID) error
 | |
| }
 | |
| 
 | |
| type InMemoryTrainingRepository struct {
 | |
| 	trainings map[TrainingID]Training
 | |
| 	lock      sync.RWMutex
 | |
| }
 | |
| 
 | |
| func NewInMemoryTrainingRepository() *InMemoryTrainingRepository {
 | |
| 	repo := &InMemoryTrainingRepository{
 | |
| 		trainings: make(map[TrainingID]Training),
 | |
| 	}
 | |
| 
 | |
| 	_ = repo.Create(&Training{
 | |
| 		Name:        "Kubernetes",
 | |
| 		Days:        2,
 | |
| 		Description: "Kubernetes",
 | |
| 		Pricing: []TrainingPrice{
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(450),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(2000),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(9900),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(49000),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 		},
 | |
| 	})
 | |
| 	_ = repo.Create(&Training{
 | |
| 		Name:        "Terraform",
 | |
| 		Days:        1,
 | |
| 		Description: "Terraform",
 | |
| 		Pricing: []TrainingPrice{
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(200),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(1000),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(4900),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(24000),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 		},
 | |
| 	})
 | |
| 	_ = repo.Create(&Training{
 | |
| 		Name:        "RKE2",
 | |
| 		Days:        1,
 | |
| 		Description: "RKE2",
 | |
| 		Pricing: []TrainingPrice{
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(200),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(1000),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(4900),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(24000),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 		},
 | |
| 	})
 | |
| 	_ = repo.Create(&Training{
 | |
| 		Name:        "GitHub Actions",
 | |
| 		Days:        1,
 | |
| 		Description: "GitHub Actions",
 | |
| 		Pricing: []TrainingPrice{
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(200),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(1000),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(4900),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(24000),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 		},
 | |
| 	})
 | |
| 	_ = repo.Create(&Training{
 | |
| 		Name:        "GitLab CI",
 | |
| 		Days:        1,
 | |
| 		Description: "GitLab CI",
 | |
| 		Pricing: []TrainingPrice{
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(200),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(1000),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(4900),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(24000),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 		},
 | |
| 	})
 | |
| 	_ = repo.Create(&Training{
 | |
| 		Name:        "Prometheus",
 | |
| 		Days:        2,
 | |
| 		Description: "Prometheus",
 | |
| 		Pricing: []TrainingPrice{
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(450),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(2000),
 | |
| 				Currency: currency.USD,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(9900),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     OpenTrainingPrice,
 | |
| 			},
 | |
| 			{
 | |
| 				Amount:   decimal.NewFromInt(49000),
 | |
| 				Currency: currency.CZK,
 | |
| 				Type:     CorporateTrainingPrice,
 | |
| 			},
 | |
| 		},
 | |
| 	})
 | |
| 
 | |
| 	return repo
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingRepository) Create(training *Training) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	training.ID = NewTrainingID()
 | |
| 	r.trainings[training.ID] = *training
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingRepository) FindByID(id TrainingID) (*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 TrainingID) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	_, ok := r.trainings[id]
 | |
| 	if !ok {
 | |
| 		return ErrTrainingNotFound
 | |
| 	}
 | |
| 
 | |
| 	delete(r.trainings, id)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| type TrainingDateRepository interface {
 | |
| 	Create(trainingID TrainingID, trainingDate *TrainingDate) error
 | |
| 	FindByID(id TrainingDateID) (*TrainingDate, error)
 | |
| 	FindAll() ([]TrainingDate, error)
 | |
| 	FindAllByTrainingID(trainingID TrainingID) ([]TrainingDate, error)
 | |
| 	Update(trainingDate *TrainingDate) error
 | |
| 	Delete(id TrainingDateID) error
 | |
| }
 | |
| 
 | |
| type InMemoryTrainingDateRepository struct {
 | |
| 	trainingDates   map[TrainingDateID]TrainingDate
 | |
| 	trainingToDates map[TrainingID][]TrainingDateID
 | |
| 
 | |
| 	lock sync.RWMutex
 | |
| }
 | |
| 
 | |
| func NewInMemoryTrainingDateRepository() *InMemoryTrainingDateRepository {
 | |
| 	return &InMemoryTrainingDateRepository{
 | |
| 		trainingDates:   make(map[TrainingDateID]TrainingDate),
 | |
| 		trainingToDates: make(map[TrainingID][]TrainingDateID),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingDateRepository) Create(trainingID TrainingID, trainingDate *TrainingDate) error {
 | |
| 	r.lock.Lock()
 | |
| 	defer r.lock.Unlock()
 | |
| 
 | |
| 	trainingDate.ID = NewTrainingDateID()
 | |
| 	trainingDate.trainingID = trainingID
 | |
| 
 | |
| 	r.trainingDates[trainingDate.ID] = *trainingDate
 | |
| 	r.trainingToDates[trainingID] = append(r.trainingToDates[trainingID], trainingDate.ID)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingDateRepository) FindByID(id TrainingDateID) (*TrainingDate, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	date, ok := r.trainingDates[id]
 | |
| 	if !ok {
 | |
| 		return nil, ErrTrainingDateNotFound
 | |
| 	}
 | |
| 	return &date, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingDateRepository) FindAll() ([]TrainingDate, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	dates := make([]TrainingDate, len(r.trainingDates))
 | |
| 	for _, date := range r.trainingDates {
 | |
| 		dates = append(dates, date)
 | |
| 	}
 | |
| 
 | |
| 	return dates, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingDateRepository) FindAllByTrainingID(trainingID TrainingID) ([]TrainingDate, error) {
 | |
| 	r.lock.RLock()
 | |
| 	defer r.lock.RUnlock()
 | |
| 
 | |
| 	dates := make([]TrainingDate, 0)
 | |
| 	for _, id := range r.trainingToDates[trainingID] {
 | |
| 		dates = append(dates, r.trainingDates[id])
 | |
| 	}
 | |
| 
 | |
| 	return dates, nil
 | |
| }
 | |
| 
 | |
| func (r *InMemoryTrainingDateRepository) Update(trainingDate *TrainingDate) 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 *InMemoryTrainingDateRepository) Delete(id TrainingDateID) 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
 | |
| }
 |