Dawid Wysokiński
d244dc69bf
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: twhelp/core#140
128 lines
3.4 KiB
Go
128 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.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) List(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.List(ctx, params)
|
|
if err != nil {
|
|
return nil, 0, fmt.Errorf("VillageRepository.List: %w", err)
|
|
}
|
|
|
|
return villages, count, nil
|
|
}
|
|
|
|
func (v *Village) GetByServerKeyAndID(
|
|
ctx context.Context,
|
|
serverKey string,
|
|
id int64,
|
|
includePlayer, includePlayerTribe bool,
|
|
) (domain.VillageWithRelations, error) {
|
|
villages, _, err := v.repo.List(ctx, domain.ListVillagesParams{
|
|
IDs: []int64{id},
|
|
ServerKeys: []string{serverKey},
|
|
IncludePlayer: includePlayer,
|
|
IncludePlayerTribe: includePlayerTribe,
|
|
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
|
|
}
|