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/inmemory_repository.go
Vojtech Mares 2d32c80182
feat!: add slug to training
BREAKING CHANGE: update init migration
2024-06-26 22:24:36 +02:00

299 lines
6.4 KiB
Go

package training
import (
"gitlab.mareshq.com/hq/yggdrasil/pkg/slug"
"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++
if training.Slug == "" {
training.Slug = slug.NewString(training.Name)
} else {
slugValidateErr := slug.Validate(training.Slug)
if slugValidateErr != nil {
return slugValidateErr
}
}
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()
if training.Slug == "" {
training.Slug = slug.NewString(training.Name)
} else {
slugValidateErr := slug.Validate(training.Slug)
if slugValidateErr != nil {
return slugValidateErr
}
}
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
}