1
0
Fork 0
This repository has been archived on 2025-09-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
mareshq-yggdrasil/pkg/training/repository.go

379 lines
8.5 KiB
Go

package training
import (
"sync"
"time"
"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)
FindUpcomingByTrainingID(trainingID TrainingID) ([]TrainingDate, error)
FindAllUpcoming() ([]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) FindUpcomingByTrainingID(trainingID TrainingID) ([]TrainingDate, error) {
r.lock.RLock()
defer r.lock.RUnlock()
now := time.Now()
var dates []TrainingDate
for _, id := range r.trainingToDates[trainingID] {
date := r.trainingDates[id]
if date.Date.After(now) {
dates = append(dates, date)
}
}
return dates, nil
}
func (r *InMemoryTrainingDateRepository) FindAllUpcoming() ([]TrainingDate, error) {
r.lock.RLock()
defer r.lock.RUnlock()
now := time.Now()
var dates []TrainingDate
for _, date := range r.trainingDates {
if date.Date.After(now) {
dates = append(dates, date)
}
}
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
}