This repository has been archived on 2024-04-06. You can view files and clone it, but cannot push or open issues or pull requests.
core-old/internal/service/village.go
Dawid Wysokiński f636d6ac94
All checks were successful
continuous-integration/drone/push Build is passing
refactor: village - split the List method into two (#145)
Reviewed-on: twhelp/core#145
2022-12-24 07:44:25 +00:00

122 lines
3.4 KiB
Go

package service
import (
"context"
"fmt"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
"gitea.dwysokinski.me/twhelp/core/internal/tw"
)
const (
villageChunkSize = 1000
villageMaxLimit = 500
)
//counterfeiter:generate -o internal/mock/village_repository.gen.go . VillageRepository
type VillageRepository interface {
CreateOrUpdate(ctx context.Context, params ...domain.CreateVillageParams) error
List(ctx context.Context, params domain.ListVillagesParams) ([]domain.Village, error)
ListCountWithRelations(ctx context.Context, params domain.ListVillagesParams) ([]domain.VillageWithRelations, int64, error)
}
//counterfeiter:generate -o internal/mock/village_getter.gen.go . VillageGetter
type VillageGetter interface {
GetVillages(ctx context.Context, baseURL string) ([]tw.Village, error)
}
type Village struct {
repo VillageRepository
client VillageGetter
}
func NewVillage(repo VillageRepository, client VillageGetter) *Village {
return &Village{repo: repo, client: client}
}
func (v *Village) Refresh(ctx context.Context, key, url string) (domain.RefreshVillagesResult, error) {
villages, err := v.client.GetVillages(ctx, url)
if err != nil {
return domain.RefreshVillagesResult{}, fmt.Errorf("TWClient.GetVillages: %w", err)
}
res := domain.RefreshVillagesResult{
NumVillages: int64(len(villages)),
}
for i := 0; i < len(villages); i += villageChunkSize {
end := i + villageChunkSize
if end > len(villages) {
end = len(villages)
}
chunk := villages[i:end]
params := make([]domain.CreateVillageParams, 0, len(chunk))
for _, village := range chunk {
params = append(params, domain.CreateVillageParams{
ID: village.ID,
Name: village.Name,
Points: village.Points,
X: village.X,
Y: village.Y,
Continent: village.Continent,
Bonus: village.Bonus,
PlayerID: village.PlayerID,
ProfileURL: village.ProfileURL,
ServerKey: key,
})
if village.PlayerID > 0 {
res.NumPlayerVillages++
} else {
res.NumBarbarianVillages++
}
if village.Bonus > 0 {
res.NumBonusVillages++
}
}
if err := v.repo.CreateOrUpdate(ctx, params...); err != nil {
return domain.RefreshVillagesResult{}, fmt.Errorf("VillageRepository.CreateOrUpdate: %w", err)
}
}
return res, nil
}
func (v *Village) ListCountWithRelations(ctx context.Context, params domain.ListVillagesParams) ([]domain.VillageWithRelations, int64, error) {
if params.Pagination.Limit == 0 {
params.Pagination.Limit = villageMaxLimit
}
if err := validatePagination(params.Pagination, villageMaxLimit); err != nil {
return nil, 0, fmt.Errorf("validatePagination: %w", err)
}
villages, count, err := v.repo.ListCountWithRelations(ctx, params)
if err != nil {
return nil, 0, fmt.Errorf("VillageRepository.ListCountWithRelations: %w", err)
}
return villages, count, nil
}
func (v *Village) GetByServerKeyAndIDWithRelations(ctx context.Context, serverKey string, id int64) (domain.VillageWithRelations, error) {
villages, _, err := v.repo.ListCountWithRelations(ctx, domain.ListVillagesParams{
IDs: []int64{id},
ServerKeys: []string{serverKey},
Pagination: domain.Pagination{
Limit: 1,
},
})
if err != nil {
return domain.VillageWithRelations{}, fmt.Errorf("VillageRepository.List: %w", err)
}
if len(villages) == 0 {
return domain.VillageWithRelations{}, domain.VillageNotFoundError{
ID: id,
}
}
return villages[0], nil
}