bump github.com/tribalwarshelp/shared and github.com/tribalwarshelp/map-generator

This commit is contained in:
Dawid Wysokiński 2021-05-05 19:32:45 +02:00
parent cd3e429b5b
commit 0a271d1255
87 changed files with 1334 additions and 1555 deletions

View File

@ -1,4 +1,2 @@
gqlgen: gqlgen:
bash ./scripts/gqlgen-generate.sh bash ./scripts/gqlgen-generate.sh
dev:
bash ./scripts/dev.sh

View File

@ -2,13 +2,12 @@ package dailyplayerstats
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.DailyPlayerStatsFilter Filter *twmodel.DailyPlayerStatsFilter
Select bool Select bool
Count bool Count bool
Sort []string Sort []string
@ -17,5 +16,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.DailyPlayerStats, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.DailyPlayerStats, int, error)
} }

View File

@ -2,12 +2,14 @@ package repository
import ( import (
"context" "context"
"fmt" "github.com/Kichiyaki/gopgutil/v10"
"github.com/pkg/errors"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/tribalwarshelp/api/dailyplayerstats" "github.com/tribalwarshelp/api/dailyplayerstats"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -18,25 +20,21 @@ func NewPGRepository(db *pg.DB) dailyplayerstats.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg dailyplayerstats.FetchConfig) ([]*models.DailyPlayerStats, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg dailyplayerstats.FetchConfig) ([]*twmodel.DailyPlayerStats, int, error) {
var err error var err error
data := []*models.DailyPlayerStats{} var data []*twmodel.DailyPlayerStats
total := 0 total := 0
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
relationshipAndSortAppender := &models.DailyPlayerStatsRelationshipAndSortAppender{ Apply(cfg.Filter.WhereWithRelations).
Filter: &models.DailyPlayerStatsFilter{}, Apply(gopgutil.OrderAppender{
Sort: cfg.Sort, Orders: cfg.Sort,
} MaxDepth: 4,
if cfg.Filter != nil { }.Apply)
query = query.Apply(cfg.Filter.Where)
relationshipAndSortAppender.Filter = cfg.Filter
}
query = query.Apply(relationshipAndSortAppender.Append)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()
@ -47,9 +45,9 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg dailyplayerstats.FetchC
} }
if err != nil && err != pg.ErrNoRows { if err != nil && err != pg.ErrNoRows {
if strings.Contains(err.Error(), `relation "`+cfg.Server) { if strings.Contains(err.Error(), `relation "`+cfg.Server) {
return nil, 0, fmt.Errorf("Server not found") return nil, 0, errors.New("Server not found")
} }
return nil, 0, fmt.Errorf("Internal server error") return nil, 0, errors.New("Internal server error")
} }
return data, total, nil return data, total, nil

View File

@ -2,10 +2,9 @@ package dailyplayerstats
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.DailyPlayerStats, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.DailyPlayerStats, int, error)
} }

View File

@ -2,11 +2,10 @@ package usecase
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/dailyplayerstats" "github.com/tribalwarshelp/api/dailyplayerstats"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -17,13 +16,12 @@ func New(repo dailyplayerstats.Repository) dailyplayerstats.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg dailyplayerstats.FetchConfig) ([]*models.DailyPlayerStats, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg dailyplayerstats.FetchConfig) ([]*twmodel.DailyPlayerStats, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.DailyPlayerStatsFilter{} cfg.Filter = &twmodel.DailyPlayerStatsFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > dailyplayerstats.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > dailyplayerstats.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = dailyplayerstats.FetchLimit cfg.Limit = dailyplayerstats.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }

View File

@ -2,13 +2,12 @@ package dailytribestats
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.DailyTribeStatsFilter Filter *twmodel.DailyTribeStatsFilter
Select bool Select bool
Count bool Count bool
Sort []string Sort []string
@ -17,5 +16,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.DailyTribeStats, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.DailyTribeStats, int, error)
} }

View File

@ -3,11 +3,13 @@ package repository
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/Kichiyaki/gopgutil/v10"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/tribalwarshelp/api/dailytribestats" "github.com/tribalwarshelp/api/dailytribestats"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -18,25 +20,21 @@ func NewPGRepository(db *pg.DB) dailytribestats.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg dailytribestats.FetchConfig) ([]*models.DailyTribeStats, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg dailytribestats.FetchConfig) ([]*twmodel.DailyTribeStats, int, error) {
var err error var err error
data := []*models.DailyTribeStats{} data := []*twmodel.DailyTribeStats{}
total := 0 total := 0
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
relationshipAndSortAppender := &models.DailyTribeStatsRelationshipAndSortAppender{ Apply(cfg.Filter.WhereWithRelations).
Filter: &models.DailyTribeStatsFilter{}, Apply(gopgutil.OrderAppender{
Sort: cfg.Sort, Orders: cfg.Sort,
} MaxDepth: 4,
if cfg.Filter != nil { }.Apply)
query = query.Apply(cfg.Filter.Where)
relationshipAndSortAppender.Filter = cfg.Filter
}
query = query.Apply(relationshipAndSortAppender.Append)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()

View File

@ -2,10 +2,9 @@ package dailytribestats
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.DailyTribeStats, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.DailyTribeStats, int, error)
} }

View File

@ -2,11 +2,10 @@ package usecase
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/dailytribestats" "github.com/tribalwarshelp/api/dailytribestats"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -17,14 +16,12 @@ func New(repo dailytribestats.Repository) dailytribestats.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg dailytribestats.FetchConfig) ([]*models.DailyTribeStats, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg dailytribestats.FetchConfig) ([]*twmodel.DailyTribeStats, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.DailyTribeStatsFilter{} cfg.Filter = &twmodel.DailyTribeStatsFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > dailytribestats.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > dailytribestats.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = dailytribestats.FetchLimit cfg.Limit = dailytribestats.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }

View File

@ -2,13 +2,12 @@ package ennoblement
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.EnnoblementFilter Filter *twmodel.EnnoblementFilter
Select bool Select bool
Count bool Count bool
Sort []string Sort []string
@ -17,5 +16,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Ennoblement, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Ennoblement, int, error)
} }

View File

@ -2,12 +2,14 @@ package repository
import ( import (
"context" "context"
"fmt" "github.com/Kichiyaki/gopgutil/v10"
"github.com/pkg/errors"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/tribalwarshelp/api/ennoblement" "github.com/tribalwarshelp/api/ennoblement"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -18,25 +20,21 @@ func NewPGRepository(db *pg.DB) ennoblement.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg ennoblement.FetchConfig) ([]*models.Ennoblement, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg ennoblement.FetchConfig) ([]*twmodel.Ennoblement, int, error) {
var err error var err error
total := 0 total := 0
data := []*models.Ennoblement{} data := []*twmodel.Ennoblement{}
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
relationshipAndSortAppender := &models.EnnoblementRelationshipAndSortAppender{ Apply(cfg.Filter.WhereWithRelations).
Filter: &models.EnnoblementFilter{}, Apply(gopgutil.OrderAppender{
Sort: cfg.Sort, Orders: cfg.Sort,
} MaxDepth: 4,
if cfg.Filter != nil { }.Apply)
query = query.Apply(cfg.Filter.Where)
relationshipAndSortAppender.Filter = cfg.Filter
}
query = query.Apply(relationshipAndSortAppender.Append)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()
@ -47,9 +45,9 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg ennoblement.FetchConfig
} }
if err != nil && err != pg.ErrNoRows { if err != nil && err != pg.ErrNoRows {
if strings.Contains(err.Error(), `relation "`+cfg.Server) { if strings.Contains(err.Error(), `relation "`+cfg.Server) {
return nil, 0, fmt.Errorf("Server not found") return nil, 0, errors.New("Server not found")
} }
return nil, 0, fmt.Errorf("Internal server error") return nil, 0, errors.New("Internal server error")
} }
return data, total, nil return data, total, nil

View File

@ -2,10 +2,9 @@ package ennoblement
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Ennoblement, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Ennoblement, int, error)
} }

View File

@ -2,10 +2,10 @@ package usecase
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/ennoblement" "github.com/tribalwarshelp/api/ennoblement"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -16,14 +16,12 @@ func New(repo ennoblement.Repository) ennoblement.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg ennoblement.FetchConfig) ([]*models.Ennoblement, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg ennoblement.FetchConfig) ([]*twmodel.Ennoblement, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.EnnoblementFilter{} cfg.Filter = &twmodel.EnnoblementFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > ennoblement.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > ennoblement.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = ennoblement.FetchLimit cfg.Limit = ennoblement.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }

7
go.mod
View File

@ -4,8 +4,11 @@ go 1.16
require ( require (
github.com/99designs/gqlgen v0.13.0 github.com/99designs/gqlgen v0.13.0
github.com/Kichiyaki/appmode v0.0.0-20210502105643-0a26207c548d
github.com/Kichiyaki/gin-logrus v0.0.0-20210428175948-4f47ab6231a6 github.com/Kichiyaki/gin-logrus v0.0.0-20210428175948-4f47ab6231a6
github.com/Kichiyaki/go-pg-logrus-query-logger/v10 v10.0.0-20210428180109-fb97298564d9 github.com/Kichiyaki/go-pg-logrus-query-logger/v10 v10.0.0-20210428180109-fb97298564d9
github.com/Kichiyaki/gopgutil/v10 v10.0.0-20210505101614-8a71f17a0466
github.com/Kichiyaki/goutil v0.0.0-20210504132659-3d843a787db7
github.com/agnivade/levenshtein v1.1.0 // indirect github.com/agnivade/levenshtein v1.1.0 // indirect
github.com/gin-contrib/cors v1.3.1 github.com/gin-contrib/cors v1.3.1
github.com/gin-gonic/gin v1.6.3 github.com/gin-gonic/gin v1.6.3
@ -16,8 +19,8 @@ require (
github.com/onsi/gomega v1.10.4 // indirect github.com/onsi/gomega v1.10.4 // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
github.com/tribalwarshelp/map-generator v0.0.0-20210423190517-1da85d9287dc github.com/tribalwarshelp/map-generator v0.0.0-20210505172714-6520104d1450
github.com/tribalwarshelp/shared v0.0.0-20210423190057-03d8445d35dc github.com/tribalwarshelp/shared v0.0.0-20210505172413-bf85190fd66d
github.com/vektah/gqlparser/v2 v2.1.0 github.com/vektah/gqlparser/v2 v2.1.0
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect

26
go.sum
View File

@ -2,14 +2,19 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
github.com/99designs/gqlgen v0.13.0 h1:haLTcUp3Vwp80xMVEg5KRNwzfUrgFdRmtBY8fuB8scA= github.com/99designs/gqlgen v0.13.0 h1:haLTcUp3Vwp80xMVEg5KRNwzfUrgFdRmtBY8fuB8scA=
github.com/99designs/gqlgen v0.13.0/go.mod h1:NV130r6f4tpRWuAI+zsrSdooO/eWUv+Gyyoi3rEfXIk= github.com/99designs/gqlgen v0.13.0/go.mod h1:NV130r6f4tpRWuAI+zsrSdooO/eWUv+Gyyoi3rEfXIk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Kichiyaki/gin-logrus v0.0.0-20210424132338-4ac67b4af979 h1:IgLHMjg5lAVpJ0zNcInVR8Q6WloI55v8rOoTXSHGx/A= github.com/Kichiyaki/appmode v0.0.0-20210502105643-0a26207c548d h1:ApX13STtfJc2YPH5D2JnBa6+4AM2vt7a81so/MPr/bA=
github.com/Kichiyaki/gin-logrus v0.0.0-20210424132338-4ac67b4af979/go.mod h1:6ieK3YHhyNxjkbBUR3B1IsfXi+A+LeS0SEPV10iH/cg= github.com/Kichiyaki/appmode v0.0.0-20210502105643-0a26207c548d/go.mod h1:41p1KTy/fiVocPnJR2h/iXh2NvWWVBdNoZrN8TWVXUI=
github.com/Kichiyaki/gin-logrus v0.0.0-20210428175948-4f47ab6231a6 h1:abarqFzXWxx4VElTTVWJch1u01Kf6T/zLip+Uv2yUf4= github.com/Kichiyaki/gin-logrus v0.0.0-20210428175948-4f47ab6231a6 h1:abarqFzXWxx4VElTTVWJch1u01Kf6T/zLip+Uv2yUf4=
github.com/Kichiyaki/gin-logrus v0.0.0-20210428175948-4f47ab6231a6/go.mod h1:6ieK3YHhyNxjkbBUR3B1IsfXi+A+LeS0SEPV10iH/cg= github.com/Kichiyaki/gin-logrus v0.0.0-20210428175948-4f47ab6231a6/go.mod h1:6ieK3YHhyNxjkbBUR3B1IsfXi+A+LeS0SEPV10iH/cg=
github.com/Kichiyaki/go-pg-logrus-query-logger/v10 v10.0.0-20210423175217-c83fa01c60d7 h1:7IdSzhdupqm4AC3UDH9b5gdCDE2SlX6qkVC0zwqAuLA=
github.com/Kichiyaki/go-pg-logrus-query-logger/v10 v10.0.0-20210423175217-c83fa01c60d7/go.mod h1:ADHVWnGlWcRn1aGthuh7I1Lrn6zzsjkVJju151dXyDw=
github.com/Kichiyaki/go-pg-logrus-query-logger/v10 v10.0.0-20210428180109-fb97298564d9 h1:S/08K0AD4bXYeSPJKei8ZbumDy1JNARZsgYbNZgr9Tk= github.com/Kichiyaki/go-pg-logrus-query-logger/v10 v10.0.0-20210428180109-fb97298564d9 h1:S/08K0AD4bXYeSPJKei8ZbumDy1JNARZsgYbNZgr9Tk=
github.com/Kichiyaki/go-pg-logrus-query-logger/v10 v10.0.0-20210428180109-fb97298564d9/go.mod h1:ADHVWnGlWcRn1aGthuh7I1Lrn6zzsjkVJju151dXyDw= github.com/Kichiyaki/go-pg-logrus-query-logger/v10 v10.0.0-20210428180109-fb97298564d9/go.mod h1:ADHVWnGlWcRn1aGthuh7I1Lrn6zzsjkVJju151dXyDw=
github.com/Kichiyaki/go-php-serialize v0.0.0-20200601110855-47b6982acf83/go.mod h1:+iGkf5HfOVeRVd9K7qQDucIl+/Kt3MyenMa90b/O/c4=
github.com/Kichiyaki/gopgutil/v10 v10.0.0-20210505093434-655fa2df248f/go.mod h1:MSAEhr8oeK+Rhjhqyl31/8/AI88thYky80OyD8mheDA=
github.com/Kichiyaki/gopgutil/v10 v10.0.0-20210505101614-8a71f17a0466 h1:fK7dClaaUN/WV5IZgD/GbdD3YDoolNZ5oaLeNtVnfIc=
github.com/Kichiyaki/gopgutil/v10 v10.0.0-20210505101614-8a71f17a0466/go.mod h1:MSAEhr8oeK+Rhjhqyl31/8/AI88thYky80OyD8mheDA=
github.com/Kichiyaki/goutil v0.0.0-20210502095630-318d17091eab/go.mod h1:+HhI932Xb0xrCodNcCv5GPiCjLYhDxWhCtlEqMIJhB4=
github.com/Kichiyaki/goutil v0.0.0-20210504132659-3d843a787db7 h1:OU3ZA5H8fHTzaYIw9UBfH3gtWRL0XmnczlhH3E2PjV4=
github.com/Kichiyaki/goutil v0.0.0-20210504132659-3d843a787db7/go.mod h1:+HhI932Xb0xrCodNcCv5GPiCjLYhDxWhCtlEqMIJhB4=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs= github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM= github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM=
@ -150,7 +155,6 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -164,10 +168,14 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
github.com/tribalwarshelp/map-generator v0.0.0-20210423190517-1da85d9287dc h1:gNr9Tu5ujQH7wvgmapJXtyaQe+fhXCvfz+m6qYhiO1U= github.com/tribalwarshelp/map-generator v0.0.0-20210505171633-0ec559e0ee90 h1:9KG3hWBaGae1e8/+Ny7jEdwXKATnqyhipRMbZL8QsgQ=
github.com/tribalwarshelp/map-generator v0.0.0-20210423190517-1da85d9287dc/go.mod h1:odB3ZTsbWK+BbW4bEmOTmase97w9Xu3OqBiR+7+7JBA= github.com/tribalwarshelp/map-generator v0.0.0-20210505171633-0ec559e0ee90/go.mod h1:WYM9nyZLWJIpfZu1DGjTQhraUN0lwVT2fnJ1DFWMDcI=
github.com/tribalwarshelp/shared v0.0.0-20210423190057-03d8445d35dc h1:giWPsD/6WTOrQl9KT5AXrrf3KLkHSGuNpWa2CyyaM6w= github.com/tribalwarshelp/map-generator v0.0.0-20210505172714-6520104d1450 h1:Ej1AvIVPxPno6s4tr4MTg0pNlFA4E/aOxJE7uhYV3NI=
github.com/tribalwarshelp/shared v0.0.0-20210423190057-03d8445d35dc/go.mod h1:CDQvesBYmSyGDl5X37xfa+ub55ZbikrHDuIZ4AcfM8I= github.com/tribalwarshelp/map-generator v0.0.0-20210505172714-6520104d1450/go.mod h1:ND7ZOyvb9Kp/Mg8z58ZZlL8JPJFk0lsP1XnzFDuvtnk=
github.com/tribalwarshelp/shared v0.0.0-20210505171518-9aa09097fd04 h1:phczaKfpeiQt+JGnlVCuInrlv0etMk0f9RSJ9GmsgzQ=
github.com/tribalwarshelp/shared v0.0.0-20210505171518-9aa09097fd04/go.mod h1:GBnSKQrxL8Nmi3MViIzZVbyP9+ugd28gWArsSvw1iVU=
github.com/tribalwarshelp/shared v0.0.0-20210505172413-bf85190fd66d h1:aMlYOsJbYwKqHx7wAt526eIutV1Q5EnYK6b7lOzvPmk=
github.com/tribalwarshelp/shared v0.0.0-20210505172413-bf85190fd66d/go.mod h1:GBnSKQrxL8Nmi3MViIzZVbyP9+ugd28gWArsSvw1iVU=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go v1.2.5 h1:NozRHfUeEta89taVkyfsDVSy2f7v89Frft4pjnWuGuc= github.com/ugorji/go v1.2.5 h1:NozRHfUeEta89taVkyfsDVSy2f7v89Frft4pjnWuGuc=
github.com/ugorji/go v1.2.5/go.mod h1:gat2tIT8KJG8TVI8yv77nEO/KYT6dV7JE1gfUa8Xuls= github.com/ugorji/go v1.2.5/go.mod h1:gat2tIT8KJG8TVI8yv77nEO/KYT6dV7JE1gfUa8Xuls=

View File

@ -2,13 +2,13 @@ package dataloaders
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"time" "time"
"github.com/tribalwarshelp/api/player" "github.com/tribalwarshelp/api/player"
"github.com/tribalwarshelp/api/tribe" "github.com/tribalwarshelp/api/tribe"
"github.com/tribalwarshelp/api/version" "github.com/tribalwarshelp/api/version"
"github.com/tribalwarshelp/api/village" "github.com/tribalwarshelp/api/village"
"github.com/tribalwarshelp/shared/models"
) )
const ( const (
@ -31,13 +31,13 @@ func NewDataLoaders(cfg Config) *DataLoaders {
VersionByCode: &VersionLoader{ VersionByCode: &VersionLoader{
wait: wait, wait: wait,
maxBatch: 0, maxBatch: 0,
fetch: func(keys []string) ([]*models.Version, []error) { fetch: func(keys []string) ([]*twmodel.Version, []error) {
codes := []models.VersionCode{} codes := []twmodel.VersionCode{}
for _, code := range keys { for _, code := range keys {
codes = append(codes, models.VersionCode(code)) codes = append(codes, twmodel.VersionCode(code))
} }
versions, _, err := cfg.VersionRepo.Fetch(context.Background(), version.FetchConfig{ versions, _, err := cfg.VersionRepo.Fetch(context.Background(), version.FetchConfig{
Filter: &models.VersionFilter{ Filter: &twmodel.VersionFilter{
Code: codes, Code: codes,
}, },
Select: true, Select: true,
@ -46,12 +46,12 @@ func NewDataLoaders(cfg Config) *DataLoaders {
return nil, []error{err} return nil, []error{err}
} }
versionByCode := make(map[models.VersionCode]*models.Version) versionByCode := make(map[twmodel.VersionCode]*twmodel.Version)
for _, version := range versions { for _, v := range versions {
versionByCode[version.Code] = version versionByCode[v.Code] = v
} }
inOrder := make([]*models.Version, len(keys)) inOrder := make([]*twmodel.Version, len(keys))
for i, code := range codes { for i, code := range codes {
inOrder[i] = versionByCode[code] inOrder[i] = versionByCode[code]
} }

View File

@ -3,16 +3,15 @@
package dataloaders package dataloaders
import ( import (
"github.com/tribalwarshelp/shared/tw/twmodel"
"sync" "sync"
"time" "time"
"github.com/tribalwarshelp/shared/models"
) )
// PlayerLoaderConfig captures the config to create a new PlayerLoader // PlayerLoaderConfig captures the config to create a new PlayerLoader
type PlayerLoaderConfig struct { type PlayerLoaderConfig struct {
// Fetch is a method that provides the data for the loader // Fetch is a method that provides the data for the loader
Fetch func(keys []int) ([]*models.Player, []error) Fetch func(keys []int) ([]*twmodel.Player, []error)
// Wait is how long wait before sending a batch // Wait is how long wait before sending a batch
Wait time.Duration Wait time.Duration
@ -33,7 +32,7 @@ func NewPlayerLoader(config PlayerLoaderConfig) *PlayerLoader {
// PlayerLoader batches and caches requests // PlayerLoader batches and caches requests
type PlayerLoader struct { type PlayerLoader struct {
// this method provides the data for the loader // this method provides the data for the loader
fetch func(keys []int) ([]*models.Player, []error) fetch func(keys []int) ([]*twmodel.Player, []error)
// how long to done before sending a batch // how long to done before sending a batch
wait time.Duration wait time.Duration
@ -44,7 +43,7 @@ type PlayerLoader struct {
// INTERNAL // INTERNAL
// lazily created cache // lazily created cache
cache map[int]*models.Player cache map[int]*twmodel.Player
// the current batch. keys will continue to be collected until timeout is hit, // the current batch. keys will continue to be collected until timeout is hit,
// then everything will be sent to the fetch method and out to the listeners // then everything will be sent to the fetch method and out to the listeners
@ -56,25 +55,25 @@ type PlayerLoader struct {
type playerLoaderBatch struct { type playerLoaderBatch struct {
keys []int keys []int
data []*models.Player data []*twmodel.Player
error []error error []error
closing bool closing bool
done chan struct{} done chan struct{}
} }
// Load a Player by key, batching and caching will be applied automatically // Load a Player by key, batching and caching will be applied automatically
func (l *PlayerLoader) Load(key int) (*models.Player, error) { func (l *PlayerLoader) Load(key int) (*twmodel.Player, error) {
return l.LoadThunk(key)() return l.LoadThunk(key)()
} }
// LoadThunk returns a function that when called will block waiting for a Player. // LoadThunk returns a function that when called will block waiting for a Player.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *PlayerLoader) LoadThunk(key int) func() (*models.Player, error) { func (l *PlayerLoader) LoadThunk(key int) func() (*twmodel.Player, error) {
l.mu.Lock() l.mu.Lock()
if it, ok := l.cache[key]; ok { if it, ok := l.cache[key]; ok {
l.mu.Unlock() l.mu.Unlock()
return func() (*models.Player, error) { return func() (*twmodel.Player, error) {
return it, nil return it, nil
} }
} }
@ -85,10 +84,10 @@ func (l *PlayerLoader) LoadThunk(key int) func() (*models.Player, error) {
pos := batch.keyIndex(l, key) pos := batch.keyIndex(l, key)
l.mu.Unlock() l.mu.Unlock()
return func() (*models.Player, error) { return func() (*twmodel.Player, error) {
<-batch.done <-batch.done
var data *models.Player var data *twmodel.Player
if pos < len(batch.data) { if pos < len(batch.data) {
data = batch.data[pos] data = batch.data[pos]
} }
@ -113,14 +112,14 @@ func (l *PlayerLoader) LoadThunk(key int) func() (*models.Player, error) {
// LoadAll fetches many keys at once. It will be broken into appropriate sized // LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured // sub batches depending on how the loader is configured
func (l *PlayerLoader) LoadAll(keys []int) ([]*models.Player, []error) { func (l *PlayerLoader) LoadAll(keys []int) ([]*twmodel.Player, []error) {
results := make([]func() (*models.Player, error), len(keys)) results := make([]func() (*twmodel.Player, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
players := make([]*models.Player, len(keys)) players := make([]*twmodel.Player, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
players[i], errors[i] = thunk() players[i], errors[i] = thunk()
@ -131,13 +130,13 @@ func (l *PlayerLoader) LoadAll(keys []int) ([]*models.Player, []error) {
// LoadAllThunk returns a function that when called will block waiting for a Players. // LoadAllThunk returns a function that when called will block waiting for a Players.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *PlayerLoader) LoadAllThunk(keys []int) func() ([]*models.Player, []error) { func (l *PlayerLoader) LoadAllThunk(keys []int) func() ([]*twmodel.Player, []error) {
results := make([]func() (*models.Player, error), len(keys)) results := make([]func() (*twmodel.Player, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
return func() ([]*models.Player, []error) { return func() ([]*twmodel.Player, []error) {
players := make([]*models.Player, len(keys)) players := make([]*twmodel.Player, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
players[i], errors[i] = thunk() players[i], errors[i] = thunk()
@ -149,7 +148,7 @@ func (l *PlayerLoader) LoadAllThunk(keys []int) func() ([]*models.Player, []erro
// Prime the cache with the provided key and value. If the key already exists, no change is made // Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned. // and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).) // (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *PlayerLoader) Prime(key int, value *models.Player) bool { func (l *PlayerLoader) Prime(key int, value *twmodel.Player) bool {
l.mu.Lock() l.mu.Lock()
var found bool var found bool
if _, found = l.cache[key]; !found { if _, found = l.cache[key]; !found {
@ -169,9 +168,9 @@ func (l *PlayerLoader) Clear(key int) {
l.mu.Unlock() l.mu.Unlock()
} }
func (l *PlayerLoader) unsafeSet(key int, value *models.Player) { func (l *PlayerLoader) unsafeSet(key int, value *twmodel.Player) {
if l.cache == nil { if l.cache == nil {
l.cache = map[int]*models.Player{} l.cache = map[int]*twmodel.Player{}
} }
l.cache[key] = value l.cache[key] = value
} }

View File

@ -3,16 +3,15 @@
package dataloaders package dataloaders
import ( import (
"github.com/tribalwarshelp/shared/tw/twmodel"
"sync" "sync"
"time" "time"
"github.com/tribalwarshelp/shared/models"
) )
// PlayerNameChangesLoaderConfig captures the config to create a new PlayerNameChangesLoader // PlayerNameChangesLoaderConfig captures the config to create a new PlayerNameChangesLoader
type PlayerNameChangesLoaderConfig struct { type PlayerNameChangesLoaderConfig struct {
// Fetch is a method that provides the data for the loader // Fetch is a method that provides the data for the loader
Fetch func(keys []int) ([][]*models.PlayerNameChange, []error) Fetch func(keys []int) ([][]*twmodel.PlayerNameChange, []error)
// Wait is how long wait before sending a batch // Wait is how long wait before sending a batch
Wait time.Duration Wait time.Duration
@ -33,7 +32,7 @@ func NewPlayerNameChangesLoader(config PlayerNameChangesLoaderConfig) *PlayerNam
// PlayerNameChangesLoader batches and caches requests // PlayerNameChangesLoader batches and caches requests
type PlayerNameChangesLoader struct { type PlayerNameChangesLoader struct {
// this method provides the data for the loader // this method provides the data for the loader
fetch func(keys []int) ([][]*models.PlayerNameChange, []error) fetch func(keys []int) ([][]*twmodel.PlayerNameChange, []error)
// how long to done before sending a batch // how long to done before sending a batch
wait time.Duration wait time.Duration
@ -44,7 +43,7 @@ type PlayerNameChangesLoader struct {
// INTERNAL // INTERNAL
// lazily created cache // lazily created cache
cache map[int][]*models.PlayerNameChange cache map[int][]*twmodel.PlayerNameChange
// the current batch. keys will continue to be collected until timeout is hit, // the current batch. keys will continue to be collected until timeout is hit,
// then everything will be sent to the fetch method and out to the listeners // then everything will be sent to the fetch method and out to the listeners
@ -56,25 +55,25 @@ type PlayerNameChangesLoader struct {
type playerNameChangesLoaderBatch struct { type playerNameChangesLoaderBatch struct {
keys []int keys []int
data [][]*models.PlayerNameChange data [][]*twmodel.PlayerNameChange
error []error error []error
closing bool closing bool
done chan struct{} done chan struct{}
} }
// Load a PlayerNameChange by key, batching and caching will be applied automatically // Load a PlayerNameChange by key, batching and caching will be applied automatically
func (l *PlayerNameChangesLoader) Load(key int) ([]*models.PlayerNameChange, error) { func (l *PlayerNameChangesLoader) Load(key int) ([]*twmodel.PlayerNameChange, error) {
return l.LoadThunk(key)() return l.LoadThunk(key)()
} }
// LoadThunk returns a function that when called will block waiting for a PlayerNameChange. // LoadThunk returns a function that when called will block waiting for a PlayerNameChange.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *PlayerNameChangesLoader) LoadThunk(key int) func() ([]*models.PlayerNameChange, error) { func (l *PlayerNameChangesLoader) LoadThunk(key int) func() ([]*twmodel.PlayerNameChange, error) {
l.mu.Lock() l.mu.Lock()
if it, ok := l.cache[key]; ok { if it, ok := l.cache[key]; ok {
l.mu.Unlock() l.mu.Unlock()
return func() ([]*models.PlayerNameChange, error) { return func() ([]*twmodel.PlayerNameChange, error) {
return it, nil return it, nil
} }
} }
@ -85,10 +84,10 @@ func (l *PlayerNameChangesLoader) LoadThunk(key int) func() ([]*models.PlayerNam
pos := batch.keyIndex(l, key) pos := batch.keyIndex(l, key)
l.mu.Unlock() l.mu.Unlock()
return func() ([]*models.PlayerNameChange, error) { return func() ([]*twmodel.PlayerNameChange, error) {
<-batch.done <-batch.done
var data []*models.PlayerNameChange var data []*twmodel.PlayerNameChange
if pos < len(batch.data) { if pos < len(batch.data) {
data = batch.data[pos] data = batch.data[pos]
} }
@ -113,14 +112,14 @@ func (l *PlayerNameChangesLoader) LoadThunk(key int) func() ([]*models.PlayerNam
// LoadAll fetches many keys at once. It will be broken into appropriate sized // LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured // sub batches depending on how the loader is configured
func (l *PlayerNameChangesLoader) LoadAll(keys []int) ([][]*models.PlayerNameChange, []error) { func (l *PlayerNameChangesLoader) LoadAll(keys []int) ([][]*twmodel.PlayerNameChange, []error) {
results := make([]func() ([]*models.PlayerNameChange, error), len(keys)) results := make([]func() ([]*twmodel.PlayerNameChange, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
playerNameChanges := make([][]*models.PlayerNameChange, len(keys)) playerNameChanges := make([][]*twmodel.PlayerNameChange, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
playerNameChanges[i], errors[i] = thunk() playerNameChanges[i], errors[i] = thunk()
@ -131,13 +130,13 @@ func (l *PlayerNameChangesLoader) LoadAll(keys []int) ([][]*models.PlayerNameCha
// LoadAllThunk returns a function that when called will block waiting for a PlayerNameChanges. // LoadAllThunk returns a function that when called will block waiting for a PlayerNameChanges.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *PlayerNameChangesLoader) LoadAllThunk(keys []int) func() ([][]*models.PlayerNameChange, []error) { func (l *PlayerNameChangesLoader) LoadAllThunk(keys []int) func() ([][]*twmodel.PlayerNameChange, []error) {
results := make([]func() ([]*models.PlayerNameChange, error), len(keys)) results := make([]func() ([]*twmodel.PlayerNameChange, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
return func() ([][]*models.PlayerNameChange, []error) { return func() ([][]*twmodel.PlayerNameChange, []error) {
playerNameChanges := make([][]*models.PlayerNameChange, len(keys)) playerNameChanges := make([][]*twmodel.PlayerNameChange, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
playerNameChanges[i], errors[i] = thunk() playerNameChanges[i], errors[i] = thunk()
@ -149,13 +148,13 @@ func (l *PlayerNameChangesLoader) LoadAllThunk(keys []int) func() ([][]*models.P
// Prime the cache with the provided key and value. If the key already exists, no change is made // Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned. // and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).) // (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *PlayerNameChangesLoader) Prime(key int, value []*models.PlayerNameChange) bool { func (l *PlayerNameChangesLoader) Prime(key int, value []*twmodel.PlayerNameChange) bool {
l.mu.Lock() l.mu.Lock()
var found bool var found bool
if _, found = l.cache[key]; !found { if _, found = l.cache[key]; !found {
// make a copy when writing to the cache, its easy to pass a pointer in from a loop var // make a copy when writing to the cache, its easy to pass a pointer in from a loop var
// and end up with the whole cache pointing to the same value. // and end up with the whole cache pointing to the same value.
cpy := make([]*models.PlayerNameChange, len(value)) cpy := make([]*twmodel.PlayerNameChange, len(value))
copy(cpy, value) copy(cpy, value)
l.unsafeSet(key, cpy) l.unsafeSet(key, cpy)
} }
@ -170,9 +169,9 @@ func (l *PlayerNameChangesLoader) Clear(key int) {
l.mu.Unlock() l.mu.Unlock()
} }
func (l *PlayerNameChangesLoader) unsafeSet(key int, value []*models.PlayerNameChange) { func (l *PlayerNameChangesLoader) unsafeSet(key int, value []*twmodel.PlayerNameChange) {
if l.cache == nil { if l.cache == nil {
l.cache = map[int][]*models.PlayerNameChange{} l.cache = map[int][]*twmodel.PlayerNameChange{}
} }
l.cache[key] = value l.cache[key] = value
} }

View File

@ -2,10 +2,11 @@ package dataloaders
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/player" "github.com/tribalwarshelp/api/player"
"github.com/tribalwarshelp/api/tribe" "github.com/tribalwarshelp/api/tribe"
"github.com/tribalwarshelp/api/village" "github.com/tribalwarshelp/api/village"
"github.com/tribalwarshelp/shared/models"
) )
type ServerDataLoaders struct { type ServerDataLoaders struct {
@ -19,9 +20,9 @@ func NewServerDataLoaders(server string, cfg Config) *ServerDataLoaders {
PlayerByID: &PlayerLoader{ PlayerByID: &PlayerLoader{
wait: wait, wait: wait,
maxBatch: 0, maxBatch: 0,
fetch: func(ids []int) ([]*models.Player, []error) { fetch: func(ids []int) ([]*twmodel.Player, []error) {
players, _, err := cfg.PlayerRepo.Fetch(context.Background(), player.FetchConfig{ players, _, err := cfg.PlayerRepo.Fetch(context.Background(), player.FetchConfig{
Filter: &models.PlayerFilter{ Filter: &twmodel.PlayerFilter{
ID: ids, ID: ids,
}, },
Select: true, Select: true,
@ -31,12 +32,12 @@ func NewServerDataLoaders(server string, cfg Config) *ServerDataLoaders {
return nil, []error{err} return nil, []error{err}
} }
playerByID := make(map[int]*models.Player) playerByID := make(map[int]*twmodel.Player)
for _, player := range players { for _, p := range players {
playerByID[player.ID] = player playerByID[p.ID] = p
} }
inOrder := make([]*models.Player, len(ids)) inOrder := make([]*twmodel.Player, len(ids))
for i, id := range ids { for i, id := range ids {
inOrder[i] = playerByID[id] inOrder[i] = playerByID[id]
} }
@ -47,10 +48,10 @@ func NewServerDataLoaders(server string, cfg Config) *ServerDataLoaders {
TribeByID: &TribeLoader{ TribeByID: &TribeLoader{
wait: wait, wait: wait,
maxBatch: 0, maxBatch: 0,
fetch: func(ids []int) ([]*models.Tribe, []error) { fetch: func(ids []int) ([]*twmodel.Tribe, []error) {
tribes, _, err := cfg.TribeRepo.Fetch(context.Background(), tribe.FetchConfig{ tribes, _, err := cfg.TribeRepo.Fetch(context.Background(), tribe.FetchConfig{
Server: server, Server: server,
Filter: &models.TribeFilter{ Filter: &twmodel.TribeFilter{
ID: ids, ID: ids,
}, },
Select: true, Select: true,
@ -59,12 +60,12 @@ func NewServerDataLoaders(server string, cfg Config) *ServerDataLoaders {
return nil, []error{err} return nil, []error{err}
} }
tribeByID := make(map[int]*models.Tribe) tribeByID := make(map[int]*twmodel.Tribe)
for _, tribe := range tribes { for _, t := range tribes {
tribeByID[tribe.ID] = tribe tribeByID[t.ID] = t
} }
inOrder := make([]*models.Tribe, len(ids)) inOrder := make([]*twmodel.Tribe, len(ids))
for i, id := range ids { for i, id := range ids {
inOrder[i] = tribeByID[id] inOrder[i] = tribeByID[id]
} }
@ -75,11 +76,11 @@ func NewServerDataLoaders(server string, cfg Config) *ServerDataLoaders {
VillageByID: &VillageLoader{ VillageByID: &VillageLoader{
wait: wait, wait: wait,
maxBatch: 0, maxBatch: 0,
fetch: func(ids []int) ([]*models.Village, []error) { fetch: func(ids []int) ([]*twmodel.Village, []error) {
villages, _, err := cfg.VillageRepo.Fetch(context.Background(), village.FetchConfig{ villages, _, err := cfg.VillageRepo.Fetch(context.Background(), village.FetchConfig{
Server: server, Server: server,
Count: false, Count: false,
Filter: &models.VillageFilter{ Filter: &twmodel.VillageFilter{
ID: ids, ID: ids,
}, },
Select: true, Select: true,
@ -88,12 +89,12 @@ func NewServerDataLoaders(server string, cfg Config) *ServerDataLoaders {
return nil, []error{err} return nil, []error{err}
} }
villageByID := make(map[int]*models.Village) villageByID := make(map[int]*twmodel.Village)
for _, village := range villages { for _, v := range villages {
villageByID[village.ID] = village villageByID[v.ID] = v
} }
inOrder := make([]*models.Village, len(ids)) inOrder := make([]*twmodel.Village, len(ids))
for i, id := range ids { for i, id := range ids {
inOrder[i] = villageByID[id] inOrder[i] = villageByID[id]
} }

View File

@ -3,16 +3,15 @@
package dataloaders package dataloaders
import ( import (
"github.com/tribalwarshelp/shared/tw/twmodel"
"sync" "sync"
"time" "time"
"github.com/tribalwarshelp/shared/models"
) )
// TribeLoaderConfig captures the config to create a new TribeLoader // TribeLoaderConfig captures the config to create a new TribeLoader
type TribeLoaderConfig struct { type TribeLoaderConfig struct {
// Fetch is a method that provides the data for the loader // Fetch is a method that provides the data for the loader
Fetch func(keys []int) ([]*models.Tribe, []error) Fetch func(keys []int) ([]*twmodel.Tribe, []error)
// Wait is how long wait before sending a batch // Wait is how long wait before sending a batch
Wait time.Duration Wait time.Duration
@ -33,7 +32,7 @@ func NewTribeLoader(config TribeLoaderConfig) *TribeLoader {
// TribeLoader batches and caches requests // TribeLoader batches and caches requests
type TribeLoader struct { type TribeLoader struct {
// this method provides the data for the loader // this method provides the data for the loader
fetch func(keys []int) ([]*models.Tribe, []error) fetch func(keys []int) ([]*twmodel.Tribe, []error)
// how long to done before sending a batch // how long to done before sending a batch
wait time.Duration wait time.Duration
@ -44,7 +43,7 @@ type TribeLoader struct {
// INTERNAL // INTERNAL
// lazily created cache // lazily created cache
cache map[int]*models.Tribe cache map[int]*twmodel.Tribe
// the current batch. keys will continue to be collected until timeout is hit, // the current batch. keys will continue to be collected until timeout is hit,
// then everything will be sent to the fetch method and out to the listeners // then everything will be sent to the fetch method and out to the listeners
@ -56,25 +55,25 @@ type TribeLoader struct {
type tribeLoaderBatch struct { type tribeLoaderBatch struct {
keys []int keys []int
data []*models.Tribe data []*twmodel.Tribe
error []error error []error
closing bool closing bool
done chan struct{} done chan struct{}
} }
// Load a Tribe by key, batching and caching will be applied automatically // Load a Tribe by key, batching and caching will be applied automatically
func (l *TribeLoader) Load(key int) (*models.Tribe, error) { func (l *TribeLoader) Load(key int) (*twmodel.Tribe, error) {
return l.LoadThunk(key)() return l.LoadThunk(key)()
} }
// LoadThunk returns a function that when called will block waiting for a Tribe. // LoadThunk returns a function that when called will block waiting for a Tribe.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *TribeLoader) LoadThunk(key int) func() (*models.Tribe, error) { func (l *TribeLoader) LoadThunk(key int) func() (*twmodel.Tribe, error) {
l.mu.Lock() l.mu.Lock()
if it, ok := l.cache[key]; ok { if it, ok := l.cache[key]; ok {
l.mu.Unlock() l.mu.Unlock()
return func() (*models.Tribe, error) { return func() (*twmodel.Tribe, error) {
return it, nil return it, nil
} }
} }
@ -85,10 +84,10 @@ func (l *TribeLoader) LoadThunk(key int) func() (*models.Tribe, error) {
pos := batch.keyIndex(l, key) pos := batch.keyIndex(l, key)
l.mu.Unlock() l.mu.Unlock()
return func() (*models.Tribe, error) { return func() (*twmodel.Tribe, error) {
<-batch.done <-batch.done
var data *models.Tribe var data *twmodel.Tribe
if pos < len(batch.data) { if pos < len(batch.data) {
data = batch.data[pos] data = batch.data[pos]
} }
@ -113,14 +112,14 @@ func (l *TribeLoader) LoadThunk(key int) func() (*models.Tribe, error) {
// LoadAll fetches many keys at once. It will be broken into appropriate sized // LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured // sub batches depending on how the loader is configured
func (l *TribeLoader) LoadAll(keys []int) ([]*models.Tribe, []error) { func (l *TribeLoader) LoadAll(keys []int) ([]*twmodel.Tribe, []error) {
results := make([]func() (*models.Tribe, error), len(keys)) results := make([]func() (*twmodel.Tribe, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
tribes := make([]*models.Tribe, len(keys)) tribes := make([]*twmodel.Tribe, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
tribes[i], errors[i] = thunk() tribes[i], errors[i] = thunk()
@ -131,13 +130,13 @@ func (l *TribeLoader) LoadAll(keys []int) ([]*models.Tribe, []error) {
// LoadAllThunk returns a function that when called will block waiting for a Tribes. // LoadAllThunk returns a function that when called will block waiting for a Tribes.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *TribeLoader) LoadAllThunk(keys []int) func() ([]*models.Tribe, []error) { func (l *TribeLoader) LoadAllThunk(keys []int) func() ([]*twmodel.Tribe, []error) {
results := make([]func() (*models.Tribe, error), len(keys)) results := make([]func() (*twmodel.Tribe, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
return func() ([]*models.Tribe, []error) { return func() ([]*twmodel.Tribe, []error) {
tribes := make([]*models.Tribe, len(keys)) tribes := make([]*twmodel.Tribe, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
tribes[i], errors[i] = thunk() tribes[i], errors[i] = thunk()
@ -149,7 +148,7 @@ func (l *TribeLoader) LoadAllThunk(keys []int) func() ([]*models.Tribe, []error)
// Prime the cache with the provided key and value. If the key already exists, no change is made // Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned. // and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).) // (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *TribeLoader) Prime(key int, value *models.Tribe) bool { func (l *TribeLoader) Prime(key int, value *twmodel.Tribe) bool {
l.mu.Lock() l.mu.Lock()
var found bool var found bool
if _, found = l.cache[key]; !found { if _, found = l.cache[key]; !found {
@ -169,9 +168,9 @@ func (l *TribeLoader) Clear(key int) {
l.mu.Unlock() l.mu.Unlock()
} }
func (l *TribeLoader) unsafeSet(key int, value *models.Tribe) { func (l *TribeLoader) unsafeSet(key int, value *twmodel.Tribe) {
if l.cache == nil { if l.cache == nil {
l.cache = map[int]*models.Tribe{} l.cache = map[int]*twmodel.Tribe{}
} }
l.cache[key] = value l.cache[key] = value
} }

View File

@ -2,7 +2,7 @@ package dataloaders
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/models" "github.com/tribalwarshelp/shared/tw/twmodel"
) )
type VersionDataLoaders struct { type VersionDataLoaders struct {
@ -10,7 +10,7 @@ type VersionDataLoaders struct {
PlayerNameChangesByID *PlayerNameChangesLoader PlayerNameChangesByID *PlayerNameChangesLoader
} }
func NewVersionDataLoaders(versionCode models.VersionCode, cfg Config) *VersionDataLoaders { func NewVersionDataLoaders(versionCode twmodel.VersionCode, cfg Config) *VersionDataLoaders {
return &VersionDataLoaders{ return &VersionDataLoaders{
PlayerServersByID: &PlayerServersLoader{ PlayerServersByID: &PlayerServersLoader{
wait: wait, wait: wait,
@ -30,12 +30,12 @@ func NewVersionDataLoaders(versionCode models.VersionCode, cfg Config) *VersionD
PlayerNameChangesByID: &PlayerNameChangesLoader{ PlayerNameChangesByID: &PlayerNameChangesLoader{
wait: wait, wait: wait,
maxBatch: 0, maxBatch: 0,
fetch: func(keys []int) ([][]*models.PlayerNameChange, []error) { fetch: func(keys []int) ([][]*twmodel.PlayerNameChange, []error) {
playerNameChangesByID, err := cfg.PlayerRepo.FetchNameChanges(context.Background(), versionCode, keys...) playerNameChangesByID, err := cfg.PlayerRepo.FetchNameChanges(context.Background(), versionCode, keys...)
if err != nil { if err != nil {
return nil, []error{err} return nil, []error{err}
} }
inOrder := make([][]*models.PlayerNameChange, len(keys)) inOrder := make([][]*twmodel.PlayerNameChange, len(keys))
for i, id := range keys { for i, id := range keys {
inOrder[i] = playerNameChangesByID[id] inOrder[i] = playerNameChangesByID[id]
} }

View File

@ -3,16 +3,15 @@
package dataloaders package dataloaders
import ( import (
"github.com/tribalwarshelp/shared/tw/twmodel"
"sync" "sync"
"time" "time"
"github.com/tribalwarshelp/shared/models"
) )
// VersionLoaderConfig captures the config to create a new VersionLoader // VersionLoaderConfig captures the config to create a new VersionLoader
type VersionLoaderConfig struct { type VersionLoaderConfig struct {
// Fetch is a method that provides the data for the loader // Fetch is a method that provides the data for the loader
Fetch func(keys []string) ([]*models.Version, []error) Fetch func(keys []string) ([]*twmodel.Version, []error)
// Wait is how long wait before sending a batch // Wait is how long wait before sending a batch
Wait time.Duration Wait time.Duration
@ -33,7 +32,7 @@ func NewVersionLoader(config VersionLoaderConfig) *VersionLoader {
// VersionLoader batches and caches requests // VersionLoader batches and caches requests
type VersionLoader struct { type VersionLoader struct {
// this method provides the data for the loader // this method provides the data for the loader
fetch func(keys []string) ([]*models.Version, []error) fetch func(keys []string) ([]*twmodel.Version, []error)
// how long to done before sending a batch // how long to done before sending a batch
wait time.Duration wait time.Duration
@ -44,7 +43,7 @@ type VersionLoader struct {
// INTERNAL // INTERNAL
// lazily created cache // lazily created cache
cache map[string]*models.Version cache map[string]*twmodel.Version
// the current batch. keys will continue to be collected until timeout is hit, // the current batch. keys will continue to be collected until timeout is hit,
// then everything will be sent to the fetch method and out to the listeners // then everything will be sent to the fetch method and out to the listeners
@ -56,25 +55,25 @@ type VersionLoader struct {
type versionLoaderBatch struct { type versionLoaderBatch struct {
keys []string keys []string
data []*models.Version data []*twmodel.Version
error []error error []error
closing bool closing bool
done chan struct{} done chan struct{}
} }
// Load a Version by key, batching and caching will be applied automatically // Load a Version by key, batching and caching will be applied automatically
func (l *VersionLoader) Load(key string) (*models.Version, error) { func (l *VersionLoader) Load(key string) (*twmodel.Version, error) {
return l.LoadThunk(key)() return l.LoadThunk(key)()
} }
// LoadThunk returns a function that when called will block waiting for a Version. // LoadThunk returns a function that when called will block waiting for a Version.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *VersionLoader) LoadThunk(key string) func() (*models.Version, error) { func (l *VersionLoader) LoadThunk(key string) func() (*twmodel.Version, error) {
l.mu.Lock() l.mu.Lock()
if it, ok := l.cache[key]; ok { if it, ok := l.cache[key]; ok {
l.mu.Unlock() l.mu.Unlock()
return func() (*models.Version, error) { return func() (*twmodel.Version, error) {
return it, nil return it, nil
} }
} }
@ -85,10 +84,10 @@ func (l *VersionLoader) LoadThunk(key string) func() (*models.Version, error) {
pos := batch.keyIndex(l, key) pos := batch.keyIndex(l, key)
l.mu.Unlock() l.mu.Unlock()
return func() (*models.Version, error) { return func() (*twmodel.Version, error) {
<-batch.done <-batch.done
var data *models.Version var data *twmodel.Version
if pos < len(batch.data) { if pos < len(batch.data) {
data = batch.data[pos] data = batch.data[pos]
} }
@ -113,14 +112,14 @@ func (l *VersionLoader) LoadThunk(key string) func() (*models.Version, error) {
// LoadAll fetches many keys at once. It will be broken into appropriate sized // LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured // sub batches depending on how the loader is configured
func (l *VersionLoader) LoadAll(keys []string) ([]*models.Version, []error) { func (l *VersionLoader) LoadAll(keys []string) ([]*twmodel.Version, []error) {
results := make([]func() (*models.Version, error), len(keys)) results := make([]func() (*twmodel.Version, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
versions := make([]*models.Version, len(keys)) versions := make([]*twmodel.Version, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
versions[i], errors[i] = thunk() versions[i], errors[i] = thunk()
@ -131,13 +130,13 @@ func (l *VersionLoader) LoadAll(keys []string) ([]*models.Version, []error) {
// LoadAllThunk returns a function that when called will block waiting for a Versions. // LoadAllThunk returns a function that when called will block waiting for a Versions.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *VersionLoader) LoadAllThunk(keys []string) func() ([]*models.Version, []error) { func (l *VersionLoader) LoadAllThunk(keys []string) func() ([]*twmodel.Version, []error) {
results := make([]func() (*models.Version, error), len(keys)) results := make([]func() (*twmodel.Version, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
return func() ([]*models.Version, []error) { return func() ([]*twmodel.Version, []error) {
versions := make([]*models.Version, len(keys)) versions := make([]*twmodel.Version, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
versions[i], errors[i] = thunk() versions[i], errors[i] = thunk()
@ -149,7 +148,7 @@ func (l *VersionLoader) LoadAllThunk(keys []string) func() ([]*models.Version, [
// Prime the cache with the provided key and value. If the key already exists, no change is made // Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned. // and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).) // (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *VersionLoader) Prime(key string, value *models.Version) bool { func (l *VersionLoader) Prime(key string, value *twmodel.Version) bool {
l.mu.Lock() l.mu.Lock()
var found bool var found bool
if _, found = l.cache[key]; !found { if _, found = l.cache[key]; !found {
@ -169,9 +168,9 @@ func (l *VersionLoader) Clear(key string) {
l.mu.Unlock() l.mu.Unlock()
} }
func (l *VersionLoader) unsafeSet(key string, value *models.Version) { func (l *VersionLoader) unsafeSet(key string, value *twmodel.Version) {
if l.cache == nil { if l.cache == nil {
l.cache = map[string]*models.Version{} l.cache = map[string]*twmodel.Version{}
} }
l.cache[key] = value l.cache[key] = value
} }

View File

@ -3,16 +3,15 @@
package dataloaders package dataloaders
import ( import (
"github.com/tribalwarshelp/shared/tw/twmodel"
"sync" "sync"
"time" "time"
"github.com/tribalwarshelp/shared/models"
) )
// VillageLoaderConfig captures the config to create a new VillageLoader // VillageLoaderConfig captures the config to create a new VillageLoader
type VillageLoaderConfig struct { type VillageLoaderConfig struct {
// Fetch is a method that provides the data for the loader // Fetch is a method that provides the data for the loader
Fetch func(keys []int) ([]*models.Village, []error) Fetch func(keys []int) ([]*twmodel.Village, []error)
// Wait is how long wait before sending a batch // Wait is how long wait before sending a batch
Wait time.Duration Wait time.Duration
@ -33,7 +32,7 @@ func NewVillageLoader(config VillageLoaderConfig) *VillageLoader {
// VillageLoader batches and caches requests // VillageLoader batches and caches requests
type VillageLoader struct { type VillageLoader struct {
// this method provides the data for the loader // this method provides the data for the loader
fetch func(keys []int) ([]*models.Village, []error) fetch func(keys []int) ([]*twmodel.Village, []error)
// how long to done before sending a batch // how long to done before sending a batch
wait time.Duration wait time.Duration
@ -44,7 +43,7 @@ type VillageLoader struct {
// INTERNAL // INTERNAL
// lazily created cache // lazily created cache
cache map[int]*models.Village cache map[int]*twmodel.Village
// the current batch. keys will continue to be collected until timeout is hit, // the current batch. keys will continue to be collected until timeout is hit,
// then everything will be sent to the fetch method and out to the listeners // then everything will be sent to the fetch method and out to the listeners
@ -56,25 +55,25 @@ type VillageLoader struct {
type villageLoaderBatch struct { type villageLoaderBatch struct {
keys []int keys []int
data []*models.Village data []*twmodel.Village
error []error error []error
closing bool closing bool
done chan struct{} done chan struct{}
} }
// Load a Village by key, batching and caching will be applied automatically // Load a Village by key, batching and caching will be applied automatically
func (l *VillageLoader) Load(key int) (*models.Village, error) { func (l *VillageLoader) Load(key int) (*twmodel.Village, error) {
return l.LoadThunk(key)() return l.LoadThunk(key)()
} }
// LoadThunk returns a function that when called will block waiting for a Village. // LoadThunk returns a function that when called will block waiting for a Village.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *VillageLoader) LoadThunk(key int) func() (*models.Village, error) { func (l *VillageLoader) LoadThunk(key int) func() (*twmodel.Village, error) {
l.mu.Lock() l.mu.Lock()
if it, ok := l.cache[key]; ok { if it, ok := l.cache[key]; ok {
l.mu.Unlock() l.mu.Unlock()
return func() (*models.Village, error) { return func() (*twmodel.Village, error) {
return it, nil return it, nil
} }
} }
@ -85,10 +84,10 @@ func (l *VillageLoader) LoadThunk(key int) func() (*models.Village, error) {
pos := batch.keyIndex(l, key) pos := batch.keyIndex(l, key)
l.mu.Unlock() l.mu.Unlock()
return func() (*models.Village, error) { return func() (*twmodel.Village, error) {
<-batch.done <-batch.done
var data *models.Village var data *twmodel.Village
if pos < len(batch.data) { if pos < len(batch.data) {
data = batch.data[pos] data = batch.data[pos]
} }
@ -113,14 +112,14 @@ func (l *VillageLoader) LoadThunk(key int) func() (*models.Village, error) {
// LoadAll fetches many keys at once. It will be broken into appropriate sized // LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured // sub batches depending on how the loader is configured
func (l *VillageLoader) LoadAll(keys []int) ([]*models.Village, []error) { func (l *VillageLoader) LoadAll(keys []int) ([]*twmodel.Village, []error) {
results := make([]func() (*models.Village, error), len(keys)) results := make([]func() (*twmodel.Village, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
villages := make([]*models.Village, len(keys)) villages := make([]*twmodel.Village, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
villages[i], errors[i] = thunk() villages[i], errors[i] = thunk()
@ -131,13 +130,13 @@ func (l *VillageLoader) LoadAll(keys []int) ([]*models.Village, []error) {
// LoadAllThunk returns a function that when called will block waiting for a Villages. // LoadAllThunk returns a function that when called will block waiting for a Villages.
// This method should be used if you want one goroutine to make requests to many // This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called. // different data loaders without blocking until the thunk is called.
func (l *VillageLoader) LoadAllThunk(keys []int) func() ([]*models.Village, []error) { func (l *VillageLoader) LoadAllThunk(keys []int) func() ([]*twmodel.Village, []error) {
results := make([]func() (*models.Village, error), len(keys)) results := make([]func() (*twmodel.Village, error), len(keys))
for i, key := range keys { for i, key := range keys {
results[i] = l.LoadThunk(key) results[i] = l.LoadThunk(key)
} }
return func() ([]*models.Village, []error) { return func() ([]*twmodel.Village, []error) {
villages := make([]*models.Village, len(keys)) villages := make([]*twmodel.Village, len(keys))
errors := make([]error, len(keys)) errors := make([]error, len(keys))
for i, thunk := range results { for i, thunk := range results {
villages[i], errors[i] = thunk() villages[i], errors[i] = thunk()
@ -149,7 +148,7 @@ func (l *VillageLoader) LoadAllThunk(keys []int) func() ([]*models.Village, []er
// Prime the cache with the provided key and value. If the key already exists, no change is made // Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned. // and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).) // (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *VillageLoader) Prime(key int, value *models.Village) bool { func (l *VillageLoader) Prime(key int, value *twmodel.Village) bool {
l.mu.Lock() l.mu.Lock()
var found bool var found bool
if _, found = l.cache[key]; !found { if _, found = l.cache[key]; !found {
@ -169,9 +168,9 @@ func (l *VillageLoader) Clear(key int) {
l.mu.Unlock() l.mu.Unlock()
} }
func (l *VillageLoader) unsafeSet(key int, value *models.Village) { func (l *VillageLoader) unsafeSet(key int, value *twmodel.Village) {
if l.cache == nil { if l.cache == nil {
l.cache = map[int]*models.Village{} l.cache = map[int]*twmodel.Village{}
} }
l.cache[key] = value l.cache[key] = value
} }

File diff suppressed because it is too large Load Diff

View File

@ -3,75 +3,75 @@
package generated package generated
import ( import (
"github.com/tribalwarshelp/shared/models" "github.com/tribalwarshelp/shared/tw/twmodel"
) )
type DailyPlayerStats struct { type DailyPlayerStats struct {
Total int `json:"total"` Total int `json:"total"`
Items []*models.DailyPlayerStats `json:"items"` Items []*twmodel.DailyPlayerStats `json:"items"`
} }
type DailyTribeStats struct { type DailyTribeStats struct {
Total int `json:"total"` Total int `json:"total"`
Items []*models.DailyTribeStats `json:"items"` Items []*twmodel.DailyTribeStats `json:"items"`
} }
type EnnoblementList struct { type EnnoblementList struct {
Items []*models.Ennoblement `json:"items"` Items []*twmodel.Ennoblement `json:"items"`
Total int `json:"total"` Total int `json:"total"`
} }
type FoundPlayerList struct { type FoundPlayerList struct {
Items []*models.FoundPlayer `json:"items"` Items []*twmodel.FoundPlayer `json:"items"`
Total int `json:"total"` Total int `json:"total"`
} }
type FoundTribeList struct { type FoundTribeList struct {
Items []*models.FoundTribe `json:"items"` Items []*twmodel.FoundTribe `json:"items"`
Total int `json:"total"` Total int `json:"total"`
} }
type PlayerHistory struct { type PlayerHistory struct {
Total int `json:"total"` Total int `json:"total"`
Items []*models.PlayerHistory `json:"items"` Items []*twmodel.PlayerHistory `json:"items"`
} }
type PlayerList struct { type PlayerList struct {
Items []*models.Player `json:"items"` Items []*twmodel.Player `json:"items"`
Total int `json:"total"` Total int `json:"total"`
} }
type ServerList struct { type ServerList struct {
Items []*models.Server `json:"items"` Items []*twmodel.Server `json:"items"`
Total int `json:"total"` Total int `json:"total"`
} }
type ServerStats struct { type ServerStats struct {
Items []*models.ServerStats `json:"items"` Items []*twmodel.ServerStats `json:"items"`
Total int `json:"total"` Total int `json:"total"`
} }
type TribeChanges struct { type TribeChanges struct {
Total int `json:"total"` Total int `json:"total"`
Items []*models.TribeChange `json:"items"` Items []*twmodel.TribeChange `json:"items"`
} }
type TribeHistory struct { type TribeHistory struct {
Total int `json:"total"` Total int `json:"total"`
Items []*models.TribeHistory `json:"items"` Items []*twmodel.TribeHistory `json:"items"`
} }
type TribeList struct { type TribeList struct {
Items []*models.Tribe `json:"items"` Items []*twmodel.Tribe `json:"items"`
Total int `json:"total"` Total int `json:"total"`
} }
type VersionList struct { type VersionList struct {
Items []*models.Version `json:"items"` Items []*twmodel.Version `json:"items"`
Total int `json:"total"` Total int `json:"total"`
} }
type VillageList struct { type VillageList struct {
Items []*models.Village `json:"items"` Items []*twmodel.Village `json:"items"`
Total int `json:"total"` Total int `json:"total"`
} }

View File

@ -4,7 +4,7 @@ exec:
filename: generated/generated.go filename: generated/generated.go
package: generated package: generated
model: model:
filename: generated/models.go filename: generated/twmodel.go
package: generated package: generated
resolver: resolver:
filename: resolvers/resolver.go filename: resolvers/resolver.go
@ -16,104 +16,104 @@ directives:
skip_runtime: true skip_runtime: true
models: models:
VersionCode: VersionCode:
model: github.com/tribalwarshelp/shared/models.VersionCode model: github.com/tribalwarshelp/shared/twmodel.VersionCode
ServerStatus: ServerStatus:
model: github.com/tribalwarshelp/shared/models.ServerStatus model: github.com/tribalwarshelp/shared/twmodel.ServerStatus
Version: Version:
model: github.com/tribalwarshelp/shared/models.Version model: github.com/tribalwarshelp/shared/twmodel.Version
VersionFilter: VersionFilter:
model: github.com/tribalwarshelp/shared/models.VersionFilter model: github.com/tribalwarshelp/shared/twmodel.VersionFilter
Server: Server:
model: github.com/tribalwarshelp/shared/models.Server model: github.com/tribalwarshelp/shared/twmodel.Server
ServerConfig: ServerConfig:
model: github.com/tribalwarshelp/shared/models.ServerConfig model: github.com/tribalwarshelp/shared/twmodel.ServerConfig
ServerConfigBuild: ServerConfigBuild:
model: github.com/tribalwarshelp/shared/models.ServerConfigBuild model: github.com/tribalwarshelp/shared/twmodel.ServerConfigBuild
ServerConfigMisc: ServerConfigMisc:
model: github.com/tribalwarshelp/shared/models.ServerConfigMisc model: github.com/tribalwarshelp/shared/twmodel.ServerConfigMisc
ServerConfigCommands: ServerConfigCommands:
model: github.com/tribalwarshelp/shared/models.ServerConfigCommands model: github.com/tribalwarshelp/shared/twmodel.ServerConfigCommands
ServerConfigNewbie: ServerConfigNewbie:
model: github.com/tribalwarshelp/shared/models.ServerConfigNewbie model: github.com/tribalwarshelp/shared/twmodel.ServerConfigNewbie
ServerConfigGame: ServerConfigGame:
model: github.com/tribalwarshelp/shared/models.ServerConfigGame model: github.com/tribalwarshelp/shared/twmodel.ServerConfigGame
ServerConfigBuildings: ServerConfigBuildings:
model: github.com/tribalwarshelp/shared/models.ServerConfigBuildings model: github.com/tribalwarshelp/shared/twmodel.ServerConfigBuildings
ServerConfigSnob: ServerConfigSnob:
model: github.com/tribalwarshelp/shared/models.ServerConfigSnob model: github.com/tribalwarshelp/shared/twmodel.ServerConfigSnob
ServerConfigAlly: ServerConfigAlly:
model: github.com/tribalwarshelp/shared/models.ServerConfigAlly model: github.com/tribalwarshelp/shared/twmodel.ServerConfigAlly
ServerConfigCoord: ServerConfigCoord:
model: github.com/tribalwarshelp/shared/models.ServerConfigCoord model: github.com/tribalwarshelp/shared/twmodel.ServerConfigCoord
ServerConfigSitter: ServerConfigSitter:
model: github.com/tribalwarshelp/shared/models.ServerConfigSitter model: github.com/tribalwarshelp/shared/twmodel.ServerConfigSitter
ServerConfigSleep: ServerConfigSleep:
model: github.com/tribalwarshelp/shared/models.ServerConfigSleep model: github.com/tribalwarshelp/shared/twmodel.ServerConfigSleep
ServerConfigNight: ServerConfigNight:
model: github.com/tribalwarshelp/shared/models.ServerConfigNight model: github.com/tribalwarshelp/shared/twmodel.ServerConfigNight
ServerConfigWin: ServerConfigWin:
model: github.com/tribalwarshelp/shared/models.ServerConfigWin model: github.com/tribalwarshelp/shared/twmodel.ServerConfigWin
Unit: Unit:
model: github.com/tribalwarshelp/shared/models.Unit model: github.com/tribalwarshelp/shared/twmodel.Unit
UnitConfig: UnitConfig:
model: github.com/tribalwarshelp/shared/models.UnitConfig model: github.com/tribalwarshelp/shared/twmodel.UnitConfig
Building: Building:
model: github.com/tribalwarshelp/shared/models.Building model: github.com/tribalwarshelp/shared/twmodel.Building
BuildingConfig: BuildingConfig:
model: github.com/tribalwarshelp/shared/models.BuildingConfig model: github.com/tribalwarshelp/shared/twmodel.BuildingConfig
ServerFilter: ServerFilter:
model: github.com/tribalwarshelp/shared/models.ServerFilter model: github.com/tribalwarshelp/shared/twmodel.ServerFilter
Player: Player:
model: github.com/tribalwarshelp/shared/models.Player model: github.com/tribalwarshelp/shared/twmodel.Player
PlayerFilter: PlayerFilter:
model: github.com/tribalwarshelp/shared/models.PlayerFilter model: github.com/tribalwarshelp/shared/twmodel.PlayerFilter
FoundPlayer: FoundPlayer:
model: github.com/tribalwarshelp/shared/models.FoundPlayer model: github.com/tribalwarshelp/shared/twmodel.FoundPlayer
Tribe: Tribe:
model: github.com/tribalwarshelp/shared/models.Tribe model: github.com/tribalwarshelp/shared/twmodel.Tribe
TribeFilter: TribeFilter:
model: github.com/tribalwarshelp/shared/models.TribeFilter model: github.com/tribalwarshelp/shared/twmodel.TribeFilter
TribeFilterOr: TribeFilterOr:
model: github.com/tribalwarshelp/shared/models.TribeFilterOr model: github.com/tribalwarshelp/shared/twmodel.TribeFilterOr
FoundTribe: FoundTribe:
model: github.com/tribalwarshelp/shared/models.FoundTribe model: github.com/tribalwarshelp/shared/twmodel.FoundTribe
Village: Village:
model: github.com/tribalwarshelp/shared/models.Village model: github.com/tribalwarshelp/shared/twmodel.Village
VillageFilter: VillageFilter:
model: github.com/tribalwarshelp/shared/models.VillageFilter model: github.com/tribalwarshelp/shared/twmodel.VillageFilter
LiveEnnoblement: LiveEnnoblement:
model: github.com/tribalwarshelp/shared/models.LiveEnnoblement model: github.com/tribalwarshelp/shared/twmodel.LiveEnnoblement
Ennoblement: Ennoblement:
model: github.com/tribalwarshelp/shared/models.Ennoblement model: github.com/tribalwarshelp/shared/twmodel.Ennoblement
EnnoblementFilter: EnnoblementFilter:
model: github.com/tribalwarshelp/shared/models.EnnoblementFilter model: github.com/tribalwarshelp/shared/twmodel.EnnoblementFilter
EnnoblementFilterOr: EnnoblementFilterOr:
model: github.com/tribalwarshelp/shared/models.EnnoblementFilterOr model: github.com/tribalwarshelp/shared/twmodel.EnnoblementFilterOr
PlayerHistoryRecord: PlayerHistoryRecord:
model: github.com/tribalwarshelp/shared/models.PlayerHistory model: github.com/tribalwarshelp/shared/twmodel.PlayerHistory
PlayerHistoryFilter: PlayerHistoryFilter:
model: github.com/tribalwarshelp/shared/models.PlayerHistoryFilter model: github.com/tribalwarshelp/shared/twmodel.PlayerHistoryFilter
TribeHistoryRecord: TribeHistoryRecord:
model: github.com/tribalwarshelp/shared/models.TribeHistory model: github.com/tribalwarshelp/shared/twmodel.TribeHistory
TribeHistoryFilter: TribeHistoryFilter:
model: github.com/tribalwarshelp/shared/models.TribeHistoryFilter model: github.com/tribalwarshelp/shared/twmodel.TribeHistoryFilter
ServerStatsRecord: ServerStatsRecord:
model: github.com/tribalwarshelp/shared/models.ServerStats model: github.com/tribalwarshelp/shared/twmodel.ServerStats
ServerStatsFilter: ServerStatsFilter:
model: github.com/tribalwarshelp/shared/models.ServerStatsFilter model: github.com/tribalwarshelp/shared/twmodel.ServerStatsFilter
TribeChangeRecord: TribeChangeRecord:
model: github.com/tribalwarshelp/shared/models.TribeChange model: github.com/tribalwarshelp/shared/twmodel.TribeChange
TribeChangeFilter: TribeChangeFilter:
model: github.com/tribalwarshelp/shared/models.TribeChangeFilter model: github.com/tribalwarshelp/shared/twmodel.TribeChangeFilter
TribeChangeFilterOr: TribeChangeFilterOr:
model: github.com/tribalwarshelp/shared/models.TribeChangeFilterOr model: github.com/tribalwarshelp/shared/twmodel.TribeChangeFilterOr
DailyPlayerStatsRecord: DailyPlayerStatsRecord:
model: github.com/tribalwarshelp/shared/models.DailyPlayerStats model: github.com/tribalwarshelp/shared/twmodel.DailyPlayerStats
DailyPlayerStatsFilter: DailyPlayerStatsFilter:
model: github.com/tribalwarshelp/shared/models.DailyPlayerStatsFilter model: github.com/tribalwarshelp/shared/twmodel.DailyPlayerStatsFilter
DailyTribeStatsRecord: DailyTribeStatsRecord:
model: github.com/tribalwarshelp/shared/models.DailyTribeStats model: github.com/tribalwarshelp/shared/twmodel.DailyTribeStats
DailyTribeStatsFilter: DailyTribeStatsFilter:
model: github.com/tribalwarshelp/shared/models.DailyTribeStatsFilter model: github.com/tribalwarshelp/shared/twmodel.DailyTribeStatsFilter
PlayerNameChange: PlayerNameChange:
model: github.com/tribalwarshelp/shared/models.PlayerNameChange model: github.com/tribalwarshelp/shared/twmodel.PlayerNameChange

View File

@ -1,6 +1,9 @@
package querycomplexity package querycomplexity
import ( import (
"github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/dailyplayerstats" "github.com/tribalwarshelp/api/dailyplayerstats"
"github.com/tribalwarshelp/api/dailytribestats" "github.com/tribalwarshelp/api/dailytribestats"
"github.com/tribalwarshelp/api/ennoblement" "github.com/tribalwarshelp/api/ennoblement"
@ -12,10 +15,8 @@ import (
"github.com/tribalwarshelp/api/tribe" "github.com/tribalwarshelp/api/tribe"
"github.com/tribalwarshelp/api/tribechange" "github.com/tribalwarshelp/api/tribechange"
"github.com/tribalwarshelp/api/tribehistory" "github.com/tribalwarshelp/api/tribehistory"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/api/version" "github.com/tribalwarshelp/api/version"
"github.com/tribalwarshelp/api/village" "github.com/tribalwarshelp/api/village"
"github.com/tribalwarshelp/shared/models"
) )
const ( const (
@ -43,14 +44,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.DailyPlayerStats = func( complexityRoot.Query.DailyPlayerStats = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.DailyPlayerStatsFilter, filter *twmodel.DailyPlayerStatsFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, dailyplayerstats.FetchLimit), safeptr.SafeIntPointer(limit, dailyplayerstats.FetchLimit),
dailyPlayerStatsTotalFieldComplexity, dailyPlayerStatsTotalFieldComplexity,
1, 1,
) )
@ -60,14 +61,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.DailyTribeStats = func( complexityRoot.Query.DailyTribeStats = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.DailyTribeStatsFilter, filter *twmodel.DailyTribeStatsFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, dailytribestats.FetchLimit), safeptr.SafeIntPointer(limit, dailytribestats.FetchLimit),
dailyTribeStatsTotalFieldComplexity, dailyTribeStatsTotalFieldComplexity,
1, 1,
) )
@ -77,14 +78,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.Ennoblements = func( complexityRoot.Query.Ennoblements = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.EnnoblementFilter, filter *twmodel.EnnoblementFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, ennoblement.FetchLimit), safeptr.SafeIntPointer(limit, ennoblement.FetchLimit),
ennoblementsTotalFieldComplexity, ennoblementsTotalFieldComplexity,
1, 1,
) )
@ -94,14 +95,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.PlayerHistory = func( complexityRoot.Query.PlayerHistory = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.PlayerHistoryFilter, filter *twmodel.PlayerHistoryFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, playerhistory.FetchLimit), safeptr.SafeIntPointer(limit, playerhistory.FetchLimit),
playerHistoryTotalFieldComplexity, playerHistoryTotalFieldComplexity,
1, 1,
) )
@ -111,14 +112,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.TribeHistory = func( complexityRoot.Query.TribeHistory = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.TribeHistoryFilter, filter *twmodel.TribeHistoryFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, tribehistory.FetchLimit), safeptr.SafeIntPointer(limit, tribehistory.FetchLimit),
tribeHistoryTotalFieldComplexity, tribeHistoryTotalFieldComplexity,
1, 1,
) )
@ -128,14 +129,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.TribeChanges = func( complexityRoot.Query.TribeChanges = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.TribeChangeFilter, filter *twmodel.TribeChangeFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, tribechange.FetchLimit), safeptr.SafeIntPointer(limit, tribechange.FetchLimit),
tribeChangesTotalFieldComplexity, tribeChangesTotalFieldComplexity,
1, 1,
) )
@ -153,7 +154,7 @@ func GetComplexityRoot() generated.ComplexityRoot {
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, player.FetchLimit), safeptr.SafeIntPointer(limit, player.FetchLimit),
searchPlayerTotalFieldComplexity, searchPlayerTotalFieldComplexity,
3, 3,
) )
@ -170,7 +171,7 @@ func GetComplexityRoot() generated.ComplexityRoot {
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, tribe.FetchLimit), safeptr.SafeIntPointer(limit, tribe.FetchLimit),
searchTribeTotalFieldComplexity, searchTribeTotalFieldComplexity,
3, 3,
) )
@ -186,14 +187,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.Players = func( complexityRoot.Query.Players = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.PlayerFilter, filter *twmodel.PlayerFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, player.FetchLimit), safeptr.SafeIntPointer(limit, player.FetchLimit),
playersTotalFieldComplexity, playersTotalFieldComplexity,
1, 1,
) )
@ -203,14 +204,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.Tribes = func( complexityRoot.Query.Tribes = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.TribeFilter, filter *twmodel.TribeFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, tribe.FetchLimit), safeptr.SafeIntPointer(limit, tribe.FetchLimit),
tribesTotalFieldComplexity, tribesTotalFieldComplexity,
1, 1,
) )
@ -220,14 +221,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.Villages = func( complexityRoot.Query.Villages = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.VillageFilter, filter *twmodel.VillageFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, village.FetchLimit), safeptr.SafeIntPointer(limit, village.FetchLimit),
villagesTotalFieldComplexity, villagesTotalFieldComplexity,
1, 1,
) )
@ -237,14 +238,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Query.ServerStats = func( complexityRoot.Query.ServerStats = func(
childComplexity int, childComplexity int,
server string, server string,
filter *models.ServerStatsFilter, filter *twmodel.ServerStatsFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, serverstats.FetchLimit), safeptr.SafeIntPointer(limit, serverstats.FetchLimit),
serverStatsTotalFieldComplexity, serverStatsTotalFieldComplexity,
1, 1,
) )
@ -253,14 +254,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.ServerList.Total = getCountComplexity complexityRoot.ServerList.Total = getCountComplexity
complexityRoot.Query.Servers = func( complexityRoot.Query.Servers = func(
childComplexity int, childComplexity int,
filter *models.ServerFilter, filter *twmodel.ServerFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, server.FetchLimit), safeptr.SafeIntPointer(limit, server.FetchLimit),
serversTotalFieldComplexity, serversTotalFieldComplexity,
1, 1,
) )
@ -269,14 +270,14 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.VersionList.Total = getCountComplexity complexityRoot.VersionList.Total = getCountComplexity
complexityRoot.Query.Versions = func( complexityRoot.Query.Versions = func(
childComplexity int, childComplexity int,
filter *models.VersionFilter, filter *twmodel.VersionFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string, sort []string,
) int { ) int {
return computeComplexity( return computeComplexity(
childComplexity, childComplexity,
utils.SafeIntPointer(limit, version.FetchLimit), safeptr.SafeIntPointer(limit, version.FetchLimit),
versionsTotalFieldComplexity, versionsTotalFieldComplexity,
1, 1,
) )

View File

@ -2,14 +2,14 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/dailyplayerstats" "github.com/tribalwarshelp/api/dailyplayerstats"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/shared/models"
) )
func (r *dailyPlayerStatsRecordResolver) Player(ctx context.Context, obj *models.DailyPlayerStats) (*models.Player, error) { func (r *dailyPlayerStatsRecordResolver) Player(ctx context.Context, obj *twmodel.DailyPlayerStats) (*twmodel.Player, error) {
if obj.Player != nil { if obj.Player != nil {
return obj.Player, nil return obj.Player, nil
} }
@ -19,7 +19,7 @@ func (r *dailyPlayerStatsRecordResolver) Player(ctx context.Context, obj *models
func (r *queryResolver) DailyPlayerStats(ctx context.Context, func (r *queryResolver) DailyPlayerStats(ctx context.Context,
server string, server string,
filter *models.DailyPlayerStatsFilter, filter *twmodel.DailyPlayerStatsFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.DailyPlayerStats, error) { sort []string) (*generated.DailyPlayerStats, error) {
@ -29,8 +29,8 @@ func (r *queryResolver) DailyPlayerStats(ctx context.Context,
Server: server, Server: server,
Filter: filter, Filter: filter,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
Count: shouldCount(ctx), Count: shouldCount(ctx),
}) })

View File

@ -2,14 +2,14 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/dailytribestats" "github.com/tribalwarshelp/api/dailytribestats"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/shared/models"
) )
func (r *dailyTribeStatsRecordResolver) Tribe(ctx context.Context, obj *models.DailyTribeStats) (*models.Tribe, error) { func (r *dailyTribeStatsRecordResolver) Tribe(ctx context.Context, obj *twmodel.DailyTribeStats) (*twmodel.Tribe, error) {
if obj.Tribe != nil { if obj.Tribe != nil {
return obj.Tribe, nil return obj.Tribe, nil
} }
@ -19,7 +19,7 @@ func (r *dailyTribeStatsRecordResolver) Tribe(ctx context.Context, obj *models.D
func (r *queryResolver) DailyTribeStats(ctx context.Context, func (r *queryResolver) DailyTribeStats(ctx context.Context,
server string, server string,
filter *models.DailyTribeStatsFilter, filter *twmodel.DailyTribeStatsFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.DailyTribeStats, error) { sort []string) (*generated.DailyTribeStats, error) {
@ -29,8 +29,8 @@ func (r *queryResolver) DailyTribeStats(ctx context.Context,
Server: server, Server: server,
Filter: filter, Filter: filter,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
Count: shouldCount(ctx), Count: shouldCount(ctx),
}) })

View File

@ -2,14 +2,14 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/ennoblement" "github.com/tribalwarshelp/api/ennoblement"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/shared/models"
) )
func (r *ennoblementResolver) NewOwner(ctx context.Context, obj *models.Ennoblement) (*models.Player, error) { func (r *ennoblementResolver) NewOwner(ctx context.Context, obj *twmodel.Ennoblement) (*twmodel.Player, error) {
if obj.NewOwner != nil { if obj.NewOwner != nil {
return obj.NewOwner, nil return obj.NewOwner, nil
} }
@ -17,7 +17,7 @@ func (r *ennoblementResolver) NewOwner(ctx context.Context, obj *models.Ennoblem
return getPlayer(ctx, obj.NewOwnerID), nil return getPlayer(ctx, obj.NewOwnerID), nil
} }
func (r *ennoblementResolver) NewOwnerTribe(ctx context.Context, obj *models.Ennoblement) (*models.Tribe, error) { func (r *ennoblementResolver) NewOwnerTribe(ctx context.Context, obj *twmodel.Ennoblement) (*twmodel.Tribe, error) {
if obj.NewOwnerTribe != nil { if obj.NewOwnerTribe != nil {
return obj.NewOwnerTribe, nil return obj.NewOwnerTribe, nil
} }
@ -25,7 +25,7 @@ func (r *ennoblementResolver) NewOwnerTribe(ctx context.Context, obj *models.Enn
return getTribe(ctx, obj.NewOwnerTribeID), nil return getTribe(ctx, obj.NewOwnerTribeID), nil
} }
func (r *ennoblementResolver) OldOwner(ctx context.Context, obj *models.Ennoblement) (*models.Player, error) { func (r *ennoblementResolver) OldOwner(ctx context.Context, obj *twmodel.Ennoblement) (*twmodel.Player, error) {
if obj.OldOwner != nil { if obj.OldOwner != nil {
return obj.OldOwner, nil return obj.OldOwner, nil
} }
@ -33,7 +33,7 @@ func (r *ennoblementResolver) OldOwner(ctx context.Context, obj *models.Ennoblem
return getPlayer(ctx, obj.OldOwnerID), nil return getPlayer(ctx, obj.OldOwnerID), nil
} }
func (r *ennoblementResolver) OldOwnerTribe(ctx context.Context, obj *models.Ennoblement) (*models.Tribe, error) { func (r *ennoblementResolver) OldOwnerTribe(ctx context.Context, obj *twmodel.Ennoblement) (*twmodel.Tribe, error) {
if obj.OldOwnerTribe != nil { if obj.OldOwnerTribe != nil {
return obj.OldOwnerTribe, nil return obj.OldOwnerTribe, nil
} }
@ -41,7 +41,7 @@ func (r *ennoblementResolver) OldOwnerTribe(ctx context.Context, obj *models.Enn
return getTribe(ctx, obj.OldOwnerTribeID), nil return getTribe(ctx, obj.OldOwnerTribeID), nil
} }
func (r *ennoblementResolver) Village(ctx context.Context, obj *models.Ennoblement) (*models.Village, error) { func (r *ennoblementResolver) Village(ctx context.Context, obj *twmodel.Ennoblement) (*twmodel.Village, error) {
if obj.Village != nil { if obj.Village != nil {
return obj.Village, nil return obj.Village, nil
} }
@ -50,7 +50,7 @@ func (r *ennoblementResolver) Village(ctx context.Context, obj *models.Ennobleme
} }
func (r *queryResolver) Ennoblements(ctx context.Context, server string, func (r *queryResolver) Ennoblements(ctx context.Context, server string,
f *models.EnnoblementFilter, f *twmodel.EnnoblementFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.EnnoblementList, error) { sort []string) (*generated.EnnoblementList, error) {
@ -60,8 +60,8 @@ func (r *queryResolver) Ennoblements(ctx context.Context, server string,
Server: server, Server: server,
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Count: shouldCount(ctx), Count: shouldCount(ctx),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
}) })

View File

@ -2,10 +2,11 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/shared/models"
) )
func getServer(ctx context.Context) (string, bool) { func getServer(ctx context.Context) (string, bool) {
@ -22,7 +23,7 @@ func getServer(ctx context.Context) (string, bool) {
return server, ok return server, ok
} }
func getPlayer(ctx context.Context, id int) *models.Player { func getPlayer(ctx context.Context, id int) *twmodel.Player {
if server, ok := getServer(ctx); ok { if server, ok := getServer(ctx); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx) dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil { if dataloaders != nil {
@ -37,7 +38,7 @@ func getPlayer(ctx context.Context, id int) *models.Player {
return nil return nil
} }
func getVillage(ctx context.Context, id int) *models.Village { func getVillage(ctx context.Context, id int) *twmodel.Village {
if server, ok := getServer(ctx); ok { if server, ok := getServer(ctx); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx) dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil { if dataloaders != nil {
@ -52,7 +53,7 @@ func getVillage(ctx context.Context, id int) *models.Village {
return nil return nil
} }
func getTribe(ctx context.Context, id int) *models.Tribe { func getTribe(ctx context.Context, id int) *twmodel.Tribe {
if server, ok := getServer(ctx); ok { if server, ok := getServer(ctx); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx) dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil { if dataloaders != nil {

View File

@ -2,16 +2,15 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/player" "github.com/tribalwarshelp/api/player"
"github.com/tribalwarshelp/shared/models"
"github.com/tribalwarshelp/shared/tw"
) )
func (r *playerResolver) Tribe(ctx context.Context, obj *models.Player) (*models.Tribe, error) { func (r *playerResolver) Tribe(ctx context.Context, obj *twmodel.Player) (*twmodel.Tribe, error) {
if obj.Tribe != nil { if obj.Tribe != nil {
return obj.Tribe, nil return obj.Tribe, nil
} }
@ -19,11 +18,11 @@ func (r *playerResolver) Tribe(ctx context.Context, obj *models.Player) (*models
return getTribe(ctx, obj.TribeID), nil return getTribe(ctx, obj.TribeID), nil
} }
func (r *playerResolver) Servers(ctx context.Context, obj *models.Player) ([]string, error) { func (r *playerResolver) Servers(ctx context.Context, obj *twmodel.Player) ([]string, error) {
versionDataLoaders := middleware.VersionDataLoadersFromContext(ctx) versionDataLoaders := middleware.VersionDataLoadersFromContext(ctx)
if versionDataLoaders != nil { if versionDataLoaders != nil {
serverKey, _ := getServer(ctx) serverKey, _ := getServer(ctx)
if loaders, ok := versionDataLoaders[tw.VersionCodeFromServerKey(serverKey)]; ok { if loaders, ok := versionDataLoaders[twmodel.VersionCodeFromServerKey(serverKey)]; ok {
servers, err := loaders.PlayerServersByID.Load(obj.ID) servers, err := loaders.PlayerServersByID.Load(obj.ID)
if err == nil { if err == nil {
return servers, nil return servers, nil
@ -33,23 +32,23 @@ func (r *playerResolver) Servers(ctx context.Context, obj *models.Player) ([]str
return []string{}, nil return []string{}, nil
} }
func (r *playerResolver) NameChanges(ctx context.Context, obj *models.Player) ([]*models.PlayerNameChange, error) { func (r *playerResolver) NameChanges(ctx context.Context, obj *twmodel.Player) ([]*twmodel.PlayerNameChange, error) {
versionDataLoaders := middleware.VersionDataLoadersFromContext(ctx) versionDataLoaders := middleware.VersionDataLoadersFromContext(ctx)
if versionDataLoaders != nil { if versionDataLoaders != nil {
serverKey, _ := getServer(ctx) serverKey, _ := getServer(ctx)
if loaders, ok := versionDataLoaders[tw.VersionCodeFromServerKey(serverKey)]; ok { if loaders, ok := versionDataLoaders[twmodel.VersionCodeFromServerKey(serverKey)]; ok {
servers, err := loaders.PlayerNameChangesByID.Load(obj.ID) servers, err := loaders.PlayerNameChangesByID.Load(obj.ID)
if err == nil { if err == nil {
return servers, nil return servers, nil
} }
} }
} }
return []*models.PlayerNameChange{}, nil return []*twmodel.PlayerNameChange{}, nil
} }
func (r *queryResolver) Players(ctx context.Context, func (r *queryResolver) Players(ctx context.Context,
server string, server string,
f *models.PlayerFilter, f *twmodel.PlayerFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.PlayerList, error) { sort []string) (*generated.PlayerList, error) {
@ -59,15 +58,15 @@ func (r *queryResolver) Players(ctx context.Context,
Server: server, Server: server,
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Count: shouldCount(ctx), Count: shouldCount(ctx),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
}) })
return list, err return list, err
} }
func (r *queryResolver) Player(ctx context.Context, server string, id int) (*models.Player, error) { func (r *queryResolver) Player(ctx context.Context, server string, id int) (*twmodel.Player, error) {
return r.PlayerUcase.GetByID(ctx, server, id) return r.PlayerUcase.GetByID(ctx, server, id)
} }
@ -82,11 +81,11 @@ func (r *queryResolver) SearchPlayer(ctx context.Context,
list := &generated.FoundPlayerList{} list := &generated.FoundPlayerList{}
list.Items, list.Total, err = r.PlayerUcase.SearchPlayer(ctx, player.SearchPlayerConfig{ list.Items, list.Total, err = r.PlayerUcase.SearchPlayer(ctx, player.SearchPlayerConfig{
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Version: version, Version: version,
Name: utils.SafeStrPointer(name, ""), Name: safeptr.SafeStringPointer(name, ""),
ID: utils.SafeIntPointer(id, 0), ID: safeptr.SafeIntPointer(id, 0),
Count: shouldCount(ctx), Count: shouldCount(ctx),
}) })
return list, err return list, err

View File

@ -2,14 +2,14 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/playerhistory" "github.com/tribalwarshelp/api/playerhistory"
"github.com/tribalwarshelp/shared/models"
) )
func (r *playerHistoryRecordResolver) Player(ctx context.Context, obj *models.PlayerHistory) (*models.Player, error) { func (r *playerHistoryRecordResolver) Player(ctx context.Context, obj *twmodel.PlayerHistory) (*twmodel.Player, error) {
if obj.Player != nil { if obj.Player != nil {
return obj.Player, nil return obj.Player, nil
} }
@ -17,7 +17,7 @@ func (r *playerHistoryRecordResolver) Player(ctx context.Context, obj *models.Pl
return getPlayer(ctx, obj.PlayerID), nil return getPlayer(ctx, obj.PlayerID), nil
} }
func (r *playerHistoryRecordResolver) Tribe(ctx context.Context, obj *models.PlayerHistory) (*models.Tribe, error) { func (r *playerHistoryRecordResolver) Tribe(ctx context.Context, obj *twmodel.PlayerHistory) (*twmodel.Tribe, error) {
if obj.Tribe != nil { if obj.Tribe != nil {
return obj.Tribe, nil return obj.Tribe, nil
} }
@ -27,7 +27,7 @@ func (r *playerHistoryRecordResolver) Tribe(ctx context.Context, obj *models.Pla
func (r *Resolver) PlayerHistory(ctx context.Context, func (r *Resolver) PlayerHistory(ctx context.Context,
server string, server string,
f *models.PlayerHistoryFilter, f *twmodel.PlayerHistoryFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.PlayerHistory, error) { sort []string) (*generated.PlayerHistory, error) {
@ -37,8 +37,8 @@ func (r *Resolver) PlayerHistory(ctx context.Context,
Server: server, Server: server,
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Count: shouldCount(ctx), Count: shouldCount(ctx),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
}) })

View File

@ -2,16 +2,16 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/server" "github.com/tribalwarshelp/api/server"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/shared/models"
) )
func (r *serverResolver) Version(ctx context.Context, obj *models.Server) (*models.Version, error) { func (r *serverResolver) Version(ctx context.Context, obj *twmodel.Server) (*twmodel.Version, error) {
loaders := middleware.DataLoadersFromContext(ctx) loaders := middleware.DataLoadersFromContext(ctx)
if loaders != nil { if loaders != nil {
lv, _ := loaders.VersionByCode.Load(obj.VersionCode.String()) lv, _ := loaders.VersionByCode.Load(obj.VersionCode.String())
@ -21,7 +21,7 @@ func (r *serverResolver) Version(ctx context.Context, obj *models.Server) (*mode
} }
func (r *queryResolver) Servers(ctx context.Context, func (r *queryResolver) Servers(ctx context.Context,
f *models.ServerFilter, f *twmodel.ServerFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.ServerList, error) { sort []string) (*generated.ServerList, error) {
@ -30,14 +30,14 @@ func (r *queryResolver) Servers(ctx context.Context,
list.Items, list.Total, err = r.ServerUcase.Fetch(ctx, server.FetchConfig{ list.Items, list.Total, err = r.ServerUcase.Fetch(ctx, server.FetchConfig{
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Count: shouldCount(ctx), Count: shouldCount(ctx),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
}) })
return list, err return list, err
} }
func (r *queryResolver) Server(ctx context.Context, key string) (*models.Server, error) { func (r *queryResolver) Server(ctx context.Context, key string) (*twmodel.Server, error) {
return r.ServerUcase.GetByKey(ctx, key) return r.ServerUcase.GetByKey(ctx, key)
} }

View File

@ -2,16 +2,16 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/serverstats" "github.com/tribalwarshelp/api/serverstats"
"github.com/tribalwarshelp/shared/models"
) )
func (r *Resolver) ServerStats(ctx context.Context, func (r *Resolver) ServerStats(ctx context.Context,
server string, server string,
f *models.ServerStatsFilter, f *twmodel.ServerStatsFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.ServerStats, error) { sort []string) (*generated.ServerStats, error) {
@ -21,8 +21,8 @@ func (r *Resolver) ServerStats(ctx context.Context,
Server: server, Server: server,
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Count: shouldCount(ctx), Count: shouldCount(ctx),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
}) })

View File

@ -2,16 +2,16 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/tribe" "github.com/tribalwarshelp/api/tribe"
"github.com/tribalwarshelp/shared/models"
) )
func (r *queryResolver) Tribes(ctx context.Context, func (r *queryResolver) Tribes(ctx context.Context,
server string, server string,
f *models.TribeFilter, f *twmodel.TribeFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.TribeList, error) { sort []string) (*generated.TribeList, error) {
@ -21,15 +21,15 @@ func (r *queryResolver) Tribes(ctx context.Context,
Server: server, Server: server,
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Count: shouldCount(ctx), Count: shouldCount(ctx),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
}) })
return list, err return list, err
} }
func (r *queryResolver) Tribe(ctx context.Context, server string, id int) (*models.Tribe, error) { func (r *queryResolver) Tribe(ctx context.Context, server string, id int) (*twmodel.Tribe, error) {
return r.TribeUcase.GetByID(ctx, server, id) return r.TribeUcase.GetByID(ctx, server, id)
} }
@ -43,8 +43,8 @@ func (r *queryResolver) SearchTribe(ctx context.Context,
list := &generated.FoundTribeList{} list := &generated.FoundTribeList{}
list.Items, list.Total, err = r.TribeUcase.SearchTribe(ctx, tribe.SearchTribeConfig{ list.Items, list.Total, err = r.TribeUcase.SearchTribe(ctx, tribe.SearchTribeConfig{
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Version: version, Version: version,
Query: query, Query: query,
Count: shouldCount(ctx), Count: shouldCount(ctx),

View File

@ -2,14 +2,14 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/tribechange" "github.com/tribalwarshelp/api/tribechange"
"github.com/tribalwarshelp/shared/models"
) )
func (r *tribeChangeRecordResolver) Player(ctx context.Context, obj *models.TribeChange) (*models.Player, error) { func (r *tribeChangeRecordResolver) Player(ctx context.Context, obj *twmodel.TribeChange) (*twmodel.Player, error) {
if obj.Player != nil { if obj.Player != nil {
return obj.Player, nil return obj.Player, nil
} }
@ -17,7 +17,7 @@ func (r *tribeChangeRecordResolver) Player(ctx context.Context, obj *models.Trib
return getPlayer(ctx, obj.PlayerID), nil return getPlayer(ctx, obj.PlayerID), nil
} }
func (r *tribeChangeRecordResolver) NewTribe(ctx context.Context, obj *models.TribeChange) (*models.Tribe, error) { func (r *tribeChangeRecordResolver) NewTribe(ctx context.Context, obj *twmodel.TribeChange) (*twmodel.Tribe, error) {
if obj.NewTribe != nil { if obj.NewTribe != nil {
return obj.NewTribe, nil return obj.NewTribe, nil
} }
@ -25,7 +25,7 @@ func (r *tribeChangeRecordResolver) NewTribe(ctx context.Context, obj *models.Tr
return getTribe(ctx, obj.NewTribeID), nil return getTribe(ctx, obj.NewTribeID), nil
} }
func (r *tribeChangeRecordResolver) OldTribe(ctx context.Context, obj *models.TribeChange) (*models.Tribe, error) { func (r *tribeChangeRecordResolver) OldTribe(ctx context.Context, obj *twmodel.TribeChange) (*twmodel.Tribe, error) {
if obj.OldTribe != nil { if obj.OldTribe != nil {
return obj.OldTribe, nil return obj.OldTribe, nil
} }
@ -35,7 +35,7 @@ func (r *tribeChangeRecordResolver) OldTribe(ctx context.Context, obj *models.Tr
func (r *Resolver) TribeChanges(ctx context.Context, func (r *Resolver) TribeChanges(ctx context.Context,
server string, server string,
f *models.TribeChangeFilter, f *twmodel.TribeChangeFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.TribeChanges, error) { sort []string) (*generated.TribeChanges, error) {
@ -44,8 +44,8 @@ func (r *Resolver) TribeChanges(ctx context.Context,
list.Items, list.Total, err = r.TribeChangeUcase.Fetch(ctx, tribechange.FetchConfig{ list.Items, list.Total, err = r.TribeChangeUcase.Fetch(ctx, tribechange.FetchConfig{
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Count: shouldCount(ctx), Count: shouldCount(ctx),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
Server: server, Server: server,

View File

@ -2,14 +2,14 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/tribehistory" "github.com/tribalwarshelp/api/tribehistory"
"github.com/tribalwarshelp/shared/models"
) )
func (r *tribeHistoryRecordResolver) Tribe(ctx context.Context, obj *models.TribeHistory) (*models.Tribe, error) { func (r *tribeHistoryRecordResolver) Tribe(ctx context.Context, obj *twmodel.TribeHistory) (*twmodel.Tribe, error) {
if obj.Tribe != nil { if obj.Tribe != nil {
return obj.Tribe, nil return obj.Tribe, nil
} }
@ -19,7 +19,7 @@ func (r *tribeHistoryRecordResolver) Tribe(ctx context.Context, obj *models.Trib
func (r *Resolver) TribeHistory(ctx context.Context, func (r *Resolver) TribeHistory(ctx context.Context,
server string, server string,
f *models.TribeHistoryFilter, f *twmodel.TribeHistoryFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.TribeHistory, error) { sort []string) (*generated.TribeHistory, error) {
@ -28,8 +28,8 @@ func (r *Resolver) TribeHistory(ctx context.Context,
list.Items, list.Total, err = r.TribeHistoryUcase.Fetch(ctx, tribehistory.FetchConfig{ list.Items, list.Total, err = r.TribeHistoryUcase.Fetch(ctx, tribehistory.FetchConfig{
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Count: shouldCount(ctx), Count: shouldCount(ctx),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
Server: server, Server: server,

View File

@ -2,15 +2,15 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/version" "github.com/tribalwarshelp/api/version"
"github.com/tribalwarshelp/shared/models"
) )
func (r *queryResolver) Versions(ctx context.Context, func (r *queryResolver) Versions(ctx context.Context,
f *models.VersionFilter, f *twmodel.VersionFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.VersionList, error) { sort []string) (*generated.VersionList, error) {
@ -19,14 +19,14 @@ func (r *queryResolver) Versions(ctx context.Context,
list.Items, list.Total, err = r.VersionUcase.Fetch(ctx, version.FetchConfig{ list.Items, list.Total, err = r.VersionUcase.Fetch(ctx, version.FetchConfig{
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
Count: shouldCount(ctx), Count: shouldCount(ctx),
}) })
return list, err return list, err
} }
func (r *queryResolver) Version(ctx context.Context, code models.VersionCode) (*models.Version, error) { func (r *queryResolver) Version(ctx context.Context, code twmodel.VersionCode) (*twmodel.Version, error) {
return r.VersionUcase.GetByCode(ctx, code) return r.VersionUcase.GetByCode(ctx, code)
} }

View File

@ -2,14 +2,14 @@ package resolvers
import ( import (
"context" "context"
"github.com/tribalwarshelp/api/utils" "github.com/Kichiyaki/goutil/safeptr"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/village" "github.com/tribalwarshelp/api/village"
"github.com/tribalwarshelp/shared/models"
) )
func (r *villageResolver) Player(ctx context.Context, obj *models.Village) (*models.Player, error) { func (r *villageResolver) Player(ctx context.Context, obj *twmodel.Village) (*twmodel.Player, error) {
if obj.Player != nil { if obj.Player != nil {
return obj.Player, nil return obj.Player, nil
} }
@ -19,7 +19,7 @@ func (r *villageResolver) Player(ctx context.Context, obj *models.Village) (*mod
func (r *queryResolver) Villages(ctx context.Context, func (r *queryResolver) Villages(ctx context.Context,
server string, server string,
f *models.VillageFilter, f *twmodel.VillageFilter,
limit *int, limit *int,
offset *int, offset *int,
sort []string) (*generated.VillageList, error) { sort []string) (*generated.VillageList, error) {
@ -28,8 +28,8 @@ func (r *queryResolver) Villages(ctx context.Context,
list.Items, list.Total, err = r.VillageUcase.Fetch(ctx, village.FetchConfig{ list.Items, list.Total, err = r.VillageUcase.Fetch(ctx, village.FetchConfig{
Filter: f, Filter: f,
Sort: sort, Sort: sort,
Limit: utils.SafeIntPointer(limit, 0), Limit: safeptr.SafeIntPointer(limit, 0),
Offset: utils.SafeIntPointer(offset, 0), Offset: safeptr.SafeIntPointer(offset, 0),
Select: shouldSelectItems(ctx), Select: shouldSelectItems(ctx),
Count: shouldCount(ctx), Count: shouldCount(ctx),
Server: server, Server: server,
@ -37,6 +37,6 @@ func (r *queryResolver) Villages(ctx context.Context,
return list, err return list, err
} }
func (r *queryResolver) Village(ctx context.Context, server string, id int) (*models.Village, error) { func (r *queryResolver) Village(ctx context.Context, server string, id int) (*twmodel.Village, error) {
return r.VillageUcase.GetByID(ctx, server, id) return r.VillageUcase.GetByID(ctx, server, id)
} }

27
main.go
View File

@ -2,11 +2,12 @@ package main
import ( import (
"context" "context"
"github.com/Kichiyaki/appmode"
"github.com/Kichiyaki/goutil/envutil"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
"strconv"
"strings" "strings"
"time" "time"
@ -14,8 +15,6 @@ import (
servermaphttpdelivery "github.com/tribalwarshelp/api/servermap/delivery/http" servermaphttpdelivery "github.com/tribalwarshelp/api/servermap/delivery/http"
"github.com/tribalwarshelp/shared/mode"
httpdelivery "github.com/tribalwarshelp/api/graphql/delivery/http" httpdelivery "github.com/tribalwarshelp/api/graphql/delivery/http"
"github.com/tribalwarshelp/api/graphql/resolvers" "github.com/tribalwarshelp/api/graphql/resolvers"
@ -59,7 +58,7 @@ import (
func init() { func init() {
os.Setenv("TZ", "UTC") os.Setenv("TZ", "UTC")
if mode.Get() == mode.DevelopmentMode { if appmode.Equals(appmode.DevelopmentMode) {
godotenv.Load(".env.local") godotenv.Load(".env.local")
} }
@ -72,7 +71,7 @@ func main() {
Password: os.Getenv("DB_PASSWORD"), Password: os.Getenv("DB_PASSWORD"),
Database: os.Getenv("DB_NAME"), Database: os.Getenv("DB_NAME"),
Addr: os.Getenv("DB_HOST") + ":" + os.Getenv("DB_PORT"), Addr: os.Getenv("DB_HOST") + ":" + os.Getenv("DB_PORT"),
PoolSize: mustParseEnvToInt("DB_POOL_SIZE"), PoolSize: envutil.GetenvInt("DB_POOL_SIZE"),
}) })
defer func() { defer func() {
if err := db.Close(); err != nil { if err := db.Close(); err != nil {
@ -109,7 +108,7 @@ func main() {
router := gin.New() router := gin.New()
router.Use(ginlogrus.Logger(logrus.WithField("hostname", "api")), gin.Recovery()) router.Use(ginlogrus.Logger(logrus.WithField("hostname", "api")), gin.Recovery())
if mode.Get() == mode.DevelopmentMode { if appmode.Equals(appmode.DevelopmentMode) {
router.Use(cors.New(cors.Config{ router.Use(cors.New(cors.Config{
AllowOriginFunc: func(string) bool { AllowOriginFunc: func(string) bool {
return true return true
@ -187,25 +186,13 @@ func main() {
logrus.Println("Server exiting") logrus.Println("Server exiting")
} }
func mustParseEnvToInt(key string) int {
str := os.Getenv(key)
if str == "" {
return 0
}
i, err := strconv.Atoi(str)
if err != nil {
return 0
}
return i
}
func setupLogger() { func setupLogger() {
if mode.Get() == mode.DevelopmentMode { if appmode.Equals(appmode.DevelopmentMode) {
logrus.SetLevel(logrus.DebugLevel) logrus.SetLevel(logrus.DebugLevel)
} }
timestampFormat := "2006-01-02 15:04:05" timestampFormat := "2006-01-02 15:04:05"
if mode.Get() == mode.ProductionMode { if appmode.Equals(appmode.ProductionMode) {
customFormatter := new(logrus.JSONFormatter) customFormatter := new(logrus.JSONFormatter)
customFormatter.TimestampFormat = timestampFormat customFormatter.TimestampFormat = timestampFormat
logrus.SetFormatter(customFormatter) logrus.SetFormatter(customFormatter)

View File

@ -2,16 +2,16 @@ package middleware
import ( import (
"context" "context"
"github.com/Kichiyaki/goutil/strutil"
"github.com/tribalwarshelp/shared/tw/twmodel"
"net/http" "net/http"
"github.com/vektah/gqlparser/v2/gqlerror" "github.com/vektah/gqlparser/v2/gqlerror"
"github.com/gin-gonic/gin"
"github.com/tribalwarshelp/api/graphql/dataloaders" "github.com/tribalwarshelp/api/graphql/dataloaders"
"github.com/tribalwarshelp/api/server" "github.com/tribalwarshelp/api/server"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
"github.com/gin-gonic/gin"
) )
var serverDataLoadersContextKey ContextKey = "serverDataLoaders" var serverDataLoadersContextKey ContextKey = "serverDataLoaders"
@ -26,9 +26,9 @@ func DataLoadersToContext(dltcc DataLoadersToContextConfig, cfg dataloaders.Conf
return func(c *gin.Context) { return func(c *gin.Context) {
ctx := c.Request.Context() ctx := c.Request.Context()
serverDataLoaders := make(map[string]*dataloaders.ServerDataLoaders) serverDataLoaders := make(map[string]*dataloaders.ServerDataLoaders)
versionDataLoaders := make(map[models.VersionCode]*dataloaders.VersionDataLoaders) versionDataLoaders := make(map[twmodel.VersionCode]*dataloaders.VersionDataLoaders)
servers, _, err := dltcc.ServerRepo.Fetch(c.Request.Context(), server.FetchConfig{ servers, _, err := dltcc.ServerRepo.Fetch(c.Request.Context(), server.FetchConfig{
Columns: []string{utils.Underscore("versionCode"), "key"}, Columns: []string{strutil.Underscore("versionCode"), "key"},
Select: true, Select: true,
}) })
if err != nil { if err != nil {
@ -65,17 +65,17 @@ func ServerDataLoadersFromContext(ctx context.Context) map[string]*dataloaders.S
return dl.(map[string]*dataloaders.ServerDataLoaders) return dl.(map[string]*dataloaders.ServerDataLoaders)
} }
func StoreVersionDataLoadersInContext(ctx context.Context, loaders map[models.VersionCode]*dataloaders.VersionDataLoaders) context.Context { func StoreVersionDataLoadersInContext(ctx context.Context, loaders map[twmodel.VersionCode]*dataloaders.VersionDataLoaders) context.Context {
return context.WithValue(ctx, versionLoadersContextKey, loaders) return context.WithValue(ctx, versionLoadersContextKey, loaders)
} }
func VersionDataLoadersFromContext(ctx context.Context) map[models.VersionCode]*dataloaders.VersionDataLoaders { func VersionDataLoadersFromContext(ctx context.Context) map[twmodel.VersionCode]*dataloaders.VersionDataLoaders {
dl := ctx.Value(versionLoadersContextKey) dl := ctx.Value(versionLoadersContextKey)
if dl == nil { if dl == nil {
return nil return nil
} }
return dl.(map[models.VersionCode]*dataloaders.VersionDataLoaders) return dl.(map[twmodel.VersionCode]*dataloaders.VersionDataLoaders)
} }
func StoreDataLoadersInContext(ctx context.Context, loaders *dataloaders.DataLoaders) context.Context { func StoreDataLoadersInContext(ctx context.Context, loaders *dataloaders.DataLoaders) context.Context {

View File

@ -2,10 +2,10 @@ package middleware
import ( import (
"context" "context"
"github.com/Kichiyaki/appmode"
"net" "net"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/tribalwarshelp/shared/mode"
) )
var limitWhitelistContextKey ContextKey = "limitWhitelist" var limitWhitelistContextKey ContextKey = "limitWhitelist"
@ -59,7 +59,7 @@ func LimitWhitelist(cfg LimitWhitelistConfig) gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
ctx := c.Request.Context() ctx := c.Request.Context()
clientIP := net.ParseIP(c.ClientIP()) clientIP := net.ParseIP(c.ClientIP())
canExceedLimit := networksAndIps.Contains(clientIP) || mode.Get() == mode.DevelopmentMode canExceedLimit := networksAndIps.Contains(clientIP) || appmode.Equals(appmode.DevelopmentMode)
ctx = StoreLimitWhitelistDataInContext(ctx, canExceedLimit) ctx = StoreLimitWhitelistDataInContext(ctx, canExceedLimit)
c.Request = c.Request.WithContext(ctx) c.Request = c.Request.WithContext(ctx)
c.Next() c.Next()

View File

@ -2,13 +2,12 @@ package player
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.PlayerFilter Filter *twmodel.PlayerFilter
Select bool Select bool
Count bool Count bool
Sort []string Sort []string
@ -27,8 +26,8 @@ type SearchPlayerConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Player, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Player, int, error)
FetchNameChanges(ctx context.Context, code models.VersionCode, playerID ...int) (map[int][]*models.PlayerNameChange, error) FetchNameChanges(ctx context.Context, code twmodel.VersionCode, playerID ...int) (map[int][]*twmodel.PlayerNameChange, error)
FetchPlayerServers(ctx context.Context, code models.VersionCode, playerID ...int) (map[int][]string, error) FetchPlayerServers(ctx context.Context, code twmodel.VersionCode, playerID ...int) (map[int][]string, error)
SearchPlayer(ctx context.Context, cfg SearchPlayerConfig) ([]*models.FoundPlayer, int, error) SearchPlayer(ctx context.Context, cfg SearchPlayerConfig) ([]*twmodel.FoundPlayer, int, error)
} }

View File

@ -2,13 +2,15 @@ package repository
import ( import (
"context" "context"
"fmt" "github.com/Kichiyaki/gopgutil/v10"
"github.com/pkg/errors"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
"github.com/tribalwarshelp/api/player" "github.com/tribalwarshelp/api/player"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -19,25 +21,21 @@ func NewPGRepository(db *pg.DB) player.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg player.FetchConfig) ([]*models.Player, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg player.FetchConfig) ([]*twmodel.Player, int, error) {
var err error var err error
data := []*models.Player{} data := []*twmodel.Player{}
total := 0 total := 0
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
relationshipAndSortAppender := &models.PlayerRelationshipAndSortAppender{ Apply(cfg.Filter.WhereWithRelations).
Filter: &models.PlayerFilter{}, Apply(gopgutil.OrderAppender{
Sort: cfg.Sort, Orders: cfg.Sort,
} MaxDepth: 4,
if cfg.Filter != nil { }.Apply)
query = query.Apply(cfg.Filter.Where)
relationshipAndSortAppender.Filter = cfg.Filter
}
query = query.Apply(relationshipAndSortAppender.Append)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()
@ -48,9 +46,9 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg player.FetchConfig) ([]
} }
if err != nil && err != pg.ErrNoRows { if err != nil && err != pg.ErrNoRows {
if strings.Contains(err.Error(), `relation "`+cfg.Server) { if strings.Contains(err.Error(), `relation "`+cfg.Server) {
return nil, 0, fmt.Errorf("Server not found") return nil, 0, errors.New("Server not found")
} }
return nil, 0, fmt.Errorf("Internal server error") return nil, 0, errors.New("Internal server error")
} }
return data, total, nil return data, total, nil
@ -61,27 +59,27 @@ type fetchPlayerServersQueryResult struct {
Servers []string `pg:",array"` Servers []string `pg:",array"`
} }
func (repo *pgRepository) FetchNameChanges(ctx context.Context, code models.VersionCode, playerID ...int) (map[int][]*models.PlayerNameChange, error) { func (repo *pgRepository) FetchNameChanges(ctx context.Context, code twmodel.VersionCode, playerID ...int) (map[int][]*twmodel.PlayerNameChange, error) {
data := []*models.PlayerNameChange{} data := []*twmodel.PlayerNameChange{}
if err := repo.Model(&data). if err := repo.Model(&data).
Context(ctx). Context(ctx).
Where("version_code = ?", code). Where("version_code = ?", code).
Where("player_id IN (?)", pg.In(playerID)). Where("player_id IN (?)", pg.In(playerID)).
Order("change_date ASC"). Order("change_date ASC").
Select(); err != nil && err != pg.ErrNoRows { Select(); err != nil && err != pg.ErrNoRows {
return nil, fmt.Errorf("Internal server error") return nil, errors.New("Internal server error")
} }
m := make(map[int][]*models.PlayerNameChange) m := make(map[int][]*twmodel.PlayerNameChange)
for _, res := range data { for _, res := range data {
m[res.PlayerID] = append(m[res.PlayerID], res) m[res.PlayerID] = append(m[res.PlayerID], res)
} }
return m, nil return m, nil
} }
func (repo *pgRepository) FetchPlayerServers(ctx context.Context, code models.VersionCode, playerID ...int) (map[int][]string, error) { func (repo *pgRepository) FetchPlayerServers(ctx context.Context, code twmodel.VersionCode, playerID ...int) (map[int][]string, error) {
data := []*fetchPlayerServersQueryResult{} data := []*fetchPlayerServersQueryResult{}
if err := repo.Model(&models.PlayerToServer{}). if err := repo.Model(&twmodel.PlayerToServer{}).
Context(ctx). Context(ctx).
Column("player_id"). Column("player_id").
ColumnExpr("array_agg(server_key) as servers"). ColumnExpr("array_agg(server_key) as servers").
@ -90,7 +88,7 @@ func (repo *pgRepository) FetchPlayerServers(ctx context.Context, code models.Ve
Where("player_id IN (?)", pg.In(playerID)). Where("player_id IN (?)", pg.In(playerID)).
Group("player_id"). Group("player_id").
Select(&data); err != nil && err != pg.ErrNoRows { Select(&data); err != nil && err != pg.ErrNoRows {
return nil, fmt.Errorf("Internal server error") return nil, errors.New("Internal server error")
} }
m := make(map[int][]string) m := make(map[int][]string)
@ -100,19 +98,19 @@ func (repo *pgRepository) FetchPlayerServers(ctx context.Context, code models.Ve
return m, nil return m, nil
} }
func (repo *pgRepository) SearchPlayer(ctx context.Context, cfg player.SearchPlayerConfig) ([]*models.FoundPlayer, int, error) { func (repo *pgRepository) SearchPlayer(ctx context.Context, cfg player.SearchPlayerConfig) ([]*twmodel.FoundPlayer, int, error) {
servers := []*models.Server{} servers := []*twmodel.Server{}
if err := repo. if err := repo.
Model(&servers). Model(&servers).
Context(ctx). Context(ctx).
Column("key"). Column("key").
Where("version_code = ?", cfg.Version). Where("version_code = ?", cfg.Version).
Select(); err != nil { Select(); err != nil {
return nil, 0, fmt.Errorf("Internal server error") return nil, 0, errors.New("Internal server error")
} }
var query *orm.Query var query *orm.Query
res := []*models.FoundPlayer{} res := []*twmodel.FoundPlayer{}
whereClause := "player.id = ?1 OR player.name ILIKE ?0" whereClause := "player.id = ?1 OR player.name ILIKE ?0"
if cfg.ID <= 0 { if cfg.ID <= 0 {
whereClause = "player.name ILIKE ?0" whereClause = "player.name ILIKE ?0"
@ -147,14 +145,17 @@ func (repo *pgRepository) SearchPlayer(ctx context.Context, cfg player.SearchPla
Table("union_q"). Table("union_q").
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset). Offset(cfg.Offset).
Order(cfg.Sort...) Apply(gopgutil.OrderAppender{
Orders: cfg.Sort,
MaxDepth: 4,
}.Apply)
if cfg.Count { if cfg.Count {
count, err = base.SelectAndCount(&res) count, err = base.SelectAndCount(&res)
} else { } else {
err = base.Select(&res) err = base.Select(&res)
} }
if err != nil && err != pg.ErrNoRows { if err != nil && err != pg.ErrNoRows {
return nil, 0, fmt.Errorf("Internal server error") return nil, 0, errors.New("Internal server error")
} }
} }

View File

@ -2,12 +2,11 @@ package player
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Player, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Player, int, error)
GetByID(ctx context.Context, server string, id int) (*models.Player, error) GetByID(ctx context.Context, server string, id int) (*twmodel.Player, error)
SearchPlayer(ctx context.Context, cfg SearchPlayerConfig) ([]*models.FoundPlayer, int, error) SearchPlayer(ctx context.Context, cfg SearchPlayerConfig) ([]*twmodel.FoundPlayer, int, error)
} }

View File

@ -3,12 +3,12 @@ package usecase
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/pkg/errors"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/player" "github.com/tribalwarshelp/api/player"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -19,22 +19,20 @@ func New(repo player.Repository) player.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg player.FetchConfig) ([]*models.Player, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg player.FetchConfig) ([]*twmodel.Player, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.PlayerFilter{} cfg.Filter = &twmodel.PlayerFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > player.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > player.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = player.FetchLimit cfg.Limit = player.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }
func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*models.Player, error) { func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*twmodel.Player, error) {
players, _, err := ucase.repo.Fetch(ctx, player.FetchConfig{ players, _, err := ucase.repo.Fetch(ctx, player.FetchConfig{
Server: server, Server: server,
Filter: &models.PlayerFilter{ Filter: &twmodel.PlayerFilter{
ID: []int{id}, ID: []int{id},
}, },
Limit: 1, Limit: 1,
@ -50,16 +48,15 @@ func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*mode
return players[0], nil return players[0], nil
} }
func (ucase *usecase) SearchPlayer(ctx context.Context, cfg player.SearchPlayerConfig) ([]*models.FoundPlayer, int, error) { func (ucase *usecase) SearchPlayer(ctx context.Context, cfg player.SearchPlayerConfig) ([]*twmodel.FoundPlayer, int, error) {
if "" == strings.TrimSpace(cfg.Version) { if "" == strings.TrimSpace(cfg.Version) {
return nil, 0, fmt.Errorf("Version is required.") return nil, 0, errors.New("Version is required.")
} }
if "" == strings.TrimSpace(cfg.Name) && cfg.ID <= 0 { if "" == strings.TrimSpace(cfg.Name) && cfg.ID <= 0 {
return nil, 0, fmt.Errorf("Your search is ambiguous. You must specify the variable 'name' or 'id'.") return nil, 0, errors.New("Your search is ambiguous. You must specify the variable 'name' or 'id'.")
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > player.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > player.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = player.FetchLimit cfg.Limit = player.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.SearchPlayer(ctx, cfg) return ucase.repo.SearchPlayer(ctx, cfg)
} }

View File

@ -2,13 +2,12 @@ package playerhistory
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.PlayerHistoryFilter Filter *twmodel.PlayerHistoryFilter
Count bool Count bool
Select bool Select bool
Sort []string Sort []string
@ -17,5 +16,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.PlayerHistory, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.PlayerHistory, int, error)
} }

View File

@ -2,12 +2,14 @@ package repository
import ( import (
"context" "context"
"fmt" "github.com/Kichiyaki/gopgutil/v10"
"github.com/pkg/errors"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/tribalwarshelp/api/playerhistory" "github.com/tribalwarshelp/api/playerhistory"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -18,25 +20,21 @@ func NewPGRepository(db *pg.DB) playerhistory.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg playerhistory.FetchConfig) ([]*models.PlayerHistory, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg playerhistory.FetchConfig) ([]*twmodel.PlayerHistory, int, error) {
var err error var err error
total := 0 total := 0
data := []*models.PlayerHistory{} data := []*twmodel.PlayerHistory{}
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
relationshipAndSortAppender := &models.PlayerHistoryRelationshipAndSortAppender{ Apply(cfg.Filter.WhereWithRelations).
Filter: &models.PlayerHistoryFilter{}, Apply(gopgutil.OrderAppender{
Sort: cfg.Sort, Orders: cfg.Sort,
} MaxDepth: 4,
if cfg.Filter != nil { }.Apply)
query = query.Apply(cfg.Filter.Where)
relationshipAndSortAppender.Filter = cfg.Filter
}
query = query.Apply(relationshipAndSortAppender.Append)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()
@ -47,9 +45,9 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg playerhistory.FetchConf
} }
if err != nil && err != pg.ErrNoRows { if err != nil && err != pg.ErrNoRows {
if strings.Contains(err.Error(), `relation "`+cfg.Server) { if strings.Contains(err.Error(), `relation "`+cfg.Server) {
return nil, 0, fmt.Errorf("Server not found") return nil, 0, errors.New("Server not found")
} }
return nil, 0, fmt.Errorf("Internal server error") return nil, 0, errors.New("Internal server error")
} }
return data, total, nil return data, total, nil

View File

@ -2,10 +2,9 @@ package playerhistory
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.PlayerHistory, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.PlayerHistory, int, error)
} }

View File

@ -2,11 +2,10 @@ package usecase
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/playerhistory" "github.com/tribalwarshelp/api/playerhistory"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -17,14 +16,12 @@ func New(repo playerhistory.Repository) playerhistory.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg playerhistory.FetchConfig) ([]*models.PlayerHistory, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg playerhistory.FetchConfig) ([]*twmodel.PlayerHistory, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.PlayerHistoryFilter{} cfg.Filter = &twmodel.PlayerHistoryFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > playerhistory.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > playerhistory.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = playerhistory.FetchLimit cfg.Limit = playerhistory.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }

View File

@ -1,5 +0,0 @@
#!/bin/sh
export MODE=development
export GIN_MODE=debug
go run -race main.go

View File

@ -2,12 +2,11 @@ package server
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Filter *models.ServerFilter Filter *twmodel.ServerFilter
Columns []string Columns []string
Select bool Select bool
Count bool Count bool
@ -17,5 +16,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Server, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Server, int, error)
} }

View File

@ -3,12 +3,14 @@ package repository
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/Kichiyaki/gopgutil/v10"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tribalwarshelp/api/server" "github.com/tribalwarshelp/api/server"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -16,7 +18,7 @@ type pgRepository struct {
} }
func NewPGRepository(db *pg.DB) (server.Repository, error) { func NewPGRepository(db *pg.DB) (server.Repository, error) {
if err := db.Model(&models.Server{}).CreateTable(&orm.CreateTableOptions{ if err := db.Model(&twmodel.Server{}).CreateTable(&orm.CreateTableOptions{
IfNotExists: true, IfNotExists: true,
}); err != nil { }); err != nil {
return nil, errors.Wrap(err, "cannot create 'servers' table") return nil, errors.Wrap(err, "cannot create 'servers' table")
@ -24,19 +26,20 @@ func NewPGRepository(db *pg.DB) (server.Repository, error) {
return &pgRepository{db}, nil return &pgRepository{db}, nil
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg server.FetchConfig) ([]*models.Server, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg server.FetchConfig) ([]*twmodel.Server, int, error) {
var err error var err error
total := 0 total := 0
data := []*models.Server{} data := []*twmodel.Server{}
query := repo. query := repo.
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Order(cfg.Sort...).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Apply(cfg.Filter.Where).
if cfg.Filter != nil { Apply(gopgutil.OrderAppender{
query = query.Apply(cfg.Filter.Where) Orders: cfg.Sort,
} MaxDepth: 4,
}.Apply)
if len(cfg.Columns) > 0 { if len(cfg.Columns) > 0 {
query = query.Column(cfg.Columns...) query = query.Column(cfg.Columns...)
} }

View File

@ -2,11 +2,10 @@ package server
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Server, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Server, int, error)
GetByKey(ctx context.Context, key string) (*models.Server, error) GetByKey(ctx context.Context, key string) (*twmodel.Server, error)
} }

View File

@ -3,11 +3,10 @@ package usecase
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/server" "github.com/tribalwarshelp/api/server"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -18,20 +17,19 @@ func New(repo server.Repository) server.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg server.FetchConfig) ([]*models.Server, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg server.FetchConfig) ([]*twmodel.Server, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.ServerFilter{} cfg.Filter = &twmodel.ServerFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > server.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > server.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = server.FetchLimit cfg.Limit = server.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }
func (ucase *usecase) GetByKey(ctx context.Context, key string) (*models.Server, error) { func (ucase *usecase) GetByKey(ctx context.Context, key string) (*twmodel.Server, error) {
servers, _, err := ucase.repo.Fetch(ctx, server.FetchConfig{ servers, _, err := ucase.repo.Fetch(ctx, server.FetchConfig{
Filter: &models.ServerFilter{ Filter: &twmodel.ServerFilter{
Key: []string{key}, Key: []string{key},
}, },
Limit: 1, Limit: 1,

View File

@ -2,17 +2,18 @@ package httpdelivery
import ( import (
"fmt" "fmt"
"github.com/Kichiyaki/appmode"
"net/http" "net/http"
"strconv" "strconv"
"time" "time"
"github.com/tribalwarshelp/map-generator/generator" "github.com/tribalwarshelp/map-generator/generator"
"github.com/tribalwarshelp/shared/mode"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/vektah/gqlparser/v2/gqlerror"
"github.com/tribalwarshelp/api/server" "github.com/tribalwarshelp/api/server"
"github.com/tribalwarshelp/api/servermap" "github.com/tribalwarshelp/api/servermap"
"github.com/vektah/gqlparser/v2/gqlerror"
) )
const ( const (
@ -43,7 +44,7 @@ func Attach(cfg Config) error {
func (h *handler) mapHandler(c *gin.Context) { func (h *handler) mapHandler(c *gin.Context) {
c.Header("Cache-Control", fmt.Sprintf(`public, max-age=%d`, imageTTL)) c.Header("Cache-Control", fmt.Sprintf(`public, max-age=%d`, imageTTL))
server, err := h.serverUsecase.GetByKey(c.Request.Context(), c.Param("server")) srv, err := h.serverUsecase.GetByKey(c.Request.Context(), c.Param("server"))
if err != nil { if err != nil {
c.JSON(http.StatusNotFound, &gqlerror.Error{ c.JSON(http.StatusNotFound, &gqlerror.Error{
Message: err.Error(), Message: err.Error(),
@ -55,7 +56,7 @@ func (h *handler) mapHandler(c *gin.Context) {
largerMarkers := c.Query("largerMarkers") largerMarkers := c.Query("largerMarkers")
markersOnly := c.Query("markersOnly") markersOnly := c.Query("markersOnly")
markers, err := h.mapUsecase.GetMarkers(c.Request.Context(), servermap.GetMarkersConfig{ markers, err := h.mapUsecase.GetMarkers(c.Request.Context(), servermap.GetMarkersConfig{
Server: server.Key, Server: srv.Key,
Tribes: c.Request.URL.Query()["tribe"], Tribes: c.Request.URL.Query()["tribe"],
Players: c.Request.URL.Query()["player"], Players: c.Request.URL.Query()["player"],
ShowBarbarianVillages: showBarbarian == "true" || showBarbarian == "1", ShowBarbarianVillages: showBarbarian == "true" || showBarbarian == "1",
@ -87,12 +88,12 @@ func (h *handler) mapHandler(c *gin.Context) {
BackgroundColor: c.Query("backgroundColor"), BackgroundColor: c.Query("backgroundColor"),
GridLineColor: c.Query("gridLineColor"), GridLineColor: c.Query("gridLineColor"),
ContinentNumberColor: c.Query("continentNumberColor"), ContinentNumberColor: c.Query("continentNumberColor"),
MapSize: server.Config.Coord.MapSize, MapSize: srv.Config.Coord.MapSize,
CenterX: centerX, CenterX: centerX,
CenterY: centerY, CenterY: centerY,
Scale: float32(scale), Scale: float32(scale),
Quality: 90, Quality: 90,
PNG: mode.Get() == mode.ProductionMode, PNG: appmode.Equals(appmode.ProductionMode),
}); err != nil { }); err != nil {
c.JSON(http.StatusBadRequest, &gqlerror.Error{ c.JSON(http.StatusBadRequest, &gqlerror.Error{
Message: err.Error(), Message: err.Error(),

View File

@ -3,16 +3,18 @@ package usecase
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/tribalwarshelp/shared/tw/twmodel"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tribalwarshelp/map-generator/generator"
"github.com/tribalwarshelp/api/servermap" "github.com/tribalwarshelp/api/servermap"
"github.com/tribalwarshelp/api/village" "github.com/tribalwarshelp/api/village"
"github.com/tribalwarshelp/map-generator/generator"
"github.com/tribalwarshelp/shared/models"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
@ -52,8 +54,8 @@ func (ucase *usecase) GetMarkers(ctx context.Context, cfg servermap.GetMarkersCo
g.Go(func() error { g.Go(func() error {
villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{ villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{
Server: cfg.Server, Server: cfg.Server,
Filter: &models.VillageFilter{ Filter: &twmodel.VillageFilter{
PlayerFilter: &models.PlayerFilter{ PlayerFilter: &twmodel.PlayerFilter{
IDNEQ: append(playerIDs, 0), IDNEQ: append(playerIDs, 0),
TribeIDNEQ: tribeIDs, TribeIDNEQ: tribeIDs,
}, },
@ -82,7 +84,7 @@ func (ucase *usecase) GetMarkers(ctx context.Context, cfg servermap.GetMarkersCo
g.Go(func() error { g.Go(func() error {
villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{ villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{
Server: cfg.Server, Server: cfg.Server,
Filter: &models.VillageFilter{ Filter: &twmodel.VillageFilter{
PlayerID: []int{0}, PlayerID: []int{0},
}, },
Select: true, Select: true,
@ -110,8 +112,8 @@ func (ucase *usecase) GetMarkers(ctx context.Context, cfg servermap.GetMarkersCo
g.Go(func() error { g.Go(func() error {
villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{ villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{
Server: cfg.Server, Server: cfg.Server,
Filter: &models.VillageFilter{ Filter: &twmodel.VillageFilter{
PlayerFilter: &models.PlayerFilter{ PlayerFilter: &twmodel.PlayerFilter{
IDNEQ: playerIDs, IDNEQ: playerIDs,
TribeID: ids, TribeID: ids,
}, },
@ -142,7 +144,7 @@ func (ucase *usecase) GetMarkers(ctx context.Context, cfg servermap.GetMarkersCo
g.Go(func() error { g.Go(func() error {
villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{ villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{
Server: cfg.Server, Server: cfg.Server,
Filter: &models.VillageFilter{ Filter: &twmodel.VillageFilter{
PlayerID: ids, PlayerID: ids,
}, },
Select: true, Select: true,

View File

@ -2,13 +2,12 @@ package serverstats
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.ServerStatsFilter Filter *twmodel.ServerStatsFilter
Select bool Select bool
Count bool Count bool
Sort []string Sort []string
@ -17,5 +16,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.ServerStats, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.ServerStats, int, error)
} }

View File

@ -3,11 +3,13 @@ package repository
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/Kichiyaki/gopgutil/v10"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/tribalwarshelp/api/serverstats" "github.com/tribalwarshelp/api/serverstats"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -18,20 +20,21 @@ func NewPGRepository(db *pg.DB) serverstats.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg serverstats.FetchConfig) ([]*models.ServerStats, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg serverstats.FetchConfig) ([]*twmodel.ServerStats, int, error) {
var err error var err error
data := []*models.ServerStats{} data := []*twmodel.ServerStats{}
total := 0 total := 0
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Order(cfg.Sort...).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
if cfg.Filter != nil { Apply(cfg.Filter.Where).
query = query.Apply(cfg.Filter.Where) Apply(gopgutil.OrderAppender{
} Orders: cfg.Sort,
MaxDepth: 4,
}.Apply)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()

View File

@ -2,10 +2,9 @@ package serverstats
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.ServerStats, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.ServerStats, int, error)
} }

View File

@ -2,11 +2,10 @@ package usecase
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/serverstats" "github.com/tribalwarshelp/api/serverstats"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -17,14 +16,14 @@ func New(repo serverstats.Repository) serverstats.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg serverstats.FetchConfig) ([]*models.ServerStats, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg serverstats.FetchConfig) ([]*twmodel.ServerStats, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.ServerStatsFilter{} cfg.Filter = &twmodel.ServerStatsFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > serverstats.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > serverstats.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = serverstats.FetchLimit cfg.Limit = serverstats.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }

View File

@ -2,13 +2,12 @@ package tribe
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.TribeFilter Filter *twmodel.TribeFilter
Count bool Count bool
Select bool Select bool
Sort []string Sort []string
@ -26,6 +25,6 @@ type SearchTribeConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Tribe, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Tribe, int, error)
SearchTribe(ctx context.Context, cfg SearchTribeConfig) ([]*models.FoundTribe, int, error) SearchTribe(ctx context.Context, cfg SearchTribeConfig) ([]*twmodel.FoundTribe, int, error)
} }

View File

@ -3,12 +3,14 @@ package repository
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/Kichiyaki/gopgutil/v10"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
"github.com/tribalwarshelp/api/tribe" "github.com/tribalwarshelp/api/tribe"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -19,20 +21,21 @@ func NewPGRepository(db *pg.DB) tribe.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg tribe.FetchConfig) ([]*models.Tribe, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg tribe.FetchConfig) ([]*twmodel.Tribe, int, error) {
var err error var err error
data := []*models.Tribe{} data := []*twmodel.Tribe{}
total := 0 total := 0
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Order(cfg.Sort...).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
if cfg.Filter != nil { Apply(cfg.Filter.Where).
query = query.Apply(cfg.Filter.Where) Apply(gopgutil.OrderAppender{
} Orders: cfg.Sort,
MaxDepth: 4,
}.Apply)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()
@ -51,8 +54,8 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg tribe.FetchConfig) ([]*
return data, total, nil return data, total, nil
} }
func (repo *pgRepository) SearchTribe(ctx context.Context, cfg tribe.SearchTribeConfig) ([]*models.FoundTribe, int, error) { func (repo *pgRepository) SearchTribe(ctx context.Context, cfg tribe.SearchTribeConfig) ([]*twmodel.FoundTribe, int, error) {
servers := []*models.Server{} servers := []*twmodel.Server{}
if err := repo. if err := repo.
Model(&servers). Model(&servers).
Context(ctx). Context(ctx).
@ -63,7 +66,7 @@ func (repo *pgRepository) SearchTribe(ctx context.Context, cfg tribe.SearchTribe
} }
var query *orm.Query var query *orm.Query
res := []*models.FoundTribe{} res := []*twmodel.FoundTribe{}
for _, server := range servers { for _, server := range servers {
safeKey := pg.Safe(server.Key) safeKey := pg.Safe(server.Key)
otherQuery := repo. otherQuery := repo.
@ -89,7 +92,10 @@ func (repo *pgRepository) SearchTribe(ctx context.Context, cfg tribe.SearchTribe
Table("union_q"). Table("union_q").
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset). Offset(cfg.Offset).
Order(cfg.Sort...) Apply(gopgutil.OrderAppender{
Orders: cfg.Sort,
MaxDepth: 4,
}.Apply)
if cfg.Count { if cfg.Count {
count, err = base.SelectAndCount(&res) count, err = base.SelectAndCount(&res)
} else { } else {

View File

@ -2,12 +2,11 @@ package tribe
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Tribe, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Tribe, int, error)
GetByID(ctx context.Context, server string, id int) (*models.Tribe, error) GetByID(ctx context.Context, server string, id int) (*twmodel.Tribe, error)
SearchTribe(ctx context.Context, cfg SearchTribeConfig) ([]*models.FoundTribe, int, error) SearchTribe(ctx context.Context, cfg SearchTribeConfig) ([]*twmodel.FoundTribe, int, error)
} }

View File

@ -3,12 +3,11 @@ package usecase
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/tribe" "github.com/tribalwarshelp/api/tribe"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -19,21 +18,19 @@ func New(repo tribe.Repository) tribe.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg tribe.FetchConfig) ([]*models.Tribe, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg tribe.FetchConfig) ([]*twmodel.Tribe, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.TribeFilter{} cfg.Filter = &twmodel.TribeFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > tribe.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > tribe.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = tribe.FetchLimit cfg.Limit = tribe.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }
func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*models.Tribe, error) { func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*twmodel.Tribe, error) {
tribes, _, err := ucase.repo.Fetch(ctx, tribe.FetchConfig{ tribes, _, err := ucase.repo.Fetch(ctx, tribe.FetchConfig{
Filter: &models.TribeFilter{ Filter: &twmodel.TribeFilter{
ID: []int{id}, ID: []int{id},
}, },
Limit: 1, Limit: 1,
@ -50,7 +47,7 @@ func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*mode
return tribes[0], nil return tribes[0], nil
} }
func (ucase *usecase) SearchTribe(ctx context.Context, cfg tribe.SearchTribeConfig) ([]*models.FoundTribe, int, error) { func (ucase *usecase) SearchTribe(ctx context.Context, cfg tribe.SearchTribeConfig) ([]*twmodel.FoundTribe, int, error) {
if "" == strings.TrimSpace(cfg.Version) { if "" == strings.TrimSpace(cfg.Version) {
return nil, 0, fmt.Errorf("Version is required.") return nil, 0, fmt.Errorf("Version is required.")
} }
@ -60,6 +57,5 @@ func (ucase *usecase) SearchTribe(ctx context.Context, cfg tribe.SearchTribeConf
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > tribe.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > tribe.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = tribe.FetchLimit cfg.Limit = tribe.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.SearchTribe(ctx, cfg) return ucase.repo.SearchTribe(ctx, cfg)
} }

View File

@ -2,13 +2,12 @@ package tribechange
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.TribeChangeFilter Filter *twmodel.TribeChangeFilter
Count bool Count bool
Select bool Select bool
Sort []string Sort []string
@ -17,5 +16,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.TribeChange, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.TribeChange, int, error)
} }

View File

@ -1,22 +0,0 @@
package repository
import (
"github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm"
"github.com/tribalwarshelp/shared/models"
)
func appendTribeChangeFilterOr(or *models.TribeChangeFilterOr) func(*orm.Query) (*orm.Query, error) {
return func(q *orm.Query) (*orm.Query, error) {
if or != nil {
if len(or.NewTribeID) > 0 {
q = q.WhereOr("new_tribe_id IN (?)", pg.In(or.NewTribeID))
}
if len(or.OldTribeID) > 0 {
q = q.WhereOr("old_tribe_id IN (?)", pg.In(or.OldTribeID))
}
}
return q, nil
}
}

View File

@ -3,11 +3,13 @@ package repository
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/Kichiyaki/gopgutil/v10"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/tribalwarshelp/api/tribechange" "github.com/tribalwarshelp/api/tribechange"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -18,25 +20,21 @@ func NewPGRepository(db *pg.DB) tribechange.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg tribechange.FetchConfig) ([]*models.TribeChange, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg tribechange.FetchConfig) ([]*twmodel.TribeChange, int, error) {
var err error var err error
total := 0 total := 0
data := []*models.TribeChange{} data := []*twmodel.TribeChange{}
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
relationshipAndSortAppender := &models.TribeChangeRelationshipAndSortAppender{ Apply(cfg.Filter.WhereWithRelations).
Filter: &models.TribeChangeFilter{}, Apply(gopgutil.OrderAppender{
Sort: cfg.Sort, Orders: cfg.Sort,
} MaxDepth: 4,
if cfg.Filter != nil { }.Apply)
query = query.Apply(cfg.Filter.Where)
relationshipAndSortAppender.Filter = cfg.Filter
}
query = query.Apply(relationshipAndSortAppender.Append)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()

View File

@ -2,10 +2,9 @@ package tribechange
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.TribeChange, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.TribeChange, int, error)
} }

View File

@ -2,11 +2,10 @@ package usecase
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/tribechange" "github.com/tribalwarshelp/api/tribechange"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -17,14 +16,12 @@ func New(repo tribechange.Repository) tribechange.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg tribechange.FetchConfig) ([]*models.TribeChange, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg tribechange.FetchConfig) ([]*twmodel.TribeChange, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.TribeChangeFilter{} cfg.Filter = &twmodel.TribeChangeFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > tribechange.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > tribechange.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = tribechange.FetchLimit cfg.Limit = tribechange.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }

View File

@ -2,13 +2,12 @@ package tribehistory
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.TribeHistoryFilter Filter *twmodel.TribeHistoryFilter
Select bool Select bool
Count bool Count bool
Sort []string Sort []string
@ -17,5 +16,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.TribeHistory, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.TribeHistory, int, error)
} }

View File

@ -3,11 +3,13 @@ package repository
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/Kichiyaki/gopgutil/v10"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/tribalwarshelp/api/tribehistory" "github.com/tribalwarshelp/api/tribehistory"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -18,25 +20,21 @@ func NewPGRepository(db *pg.DB) tribehistory.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg tribehistory.FetchConfig) ([]*models.TribeHistory, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg tribehistory.FetchConfig) ([]*twmodel.TribeHistory, int, error) {
var err error var err error
total := 0 total := 0
data := []*models.TribeHistory{} data := []*twmodel.TribeHistory{}
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
relationshipAndSortAppender := &models.TribeHistoryRelationshipAndSortAppender{ Apply(cfg.Filter.WhereWithRelations).
Filter: &models.TribeHistoryFilter{}, Apply(gopgutil.OrderAppender{
Sort: cfg.Sort, Orders: cfg.Sort,
} MaxDepth: 4,
if cfg.Filter != nil { }.Apply)
query = query.Apply(cfg.Filter.Where)
relationshipAndSortAppender.Filter = cfg.Filter
}
query = query.Apply(relationshipAndSortAppender.Append)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()

View File

@ -2,10 +2,9 @@ package tribehistory
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.TribeHistory, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.TribeHistory, int, error)
} }

View File

@ -2,11 +2,10 @@ package usecase
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/tribehistory" "github.com/tribalwarshelp/api/tribehistory"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -17,14 +16,12 @@ func New(repo tribehistory.Repository) tribehistory.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg tribehistory.FetchConfig) ([]*models.TribeHistory, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg tribehistory.FetchConfig) ([]*twmodel.TribeHistory, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.TribeHistoryFilter{} cfg.Filter = &twmodel.TribeHistoryFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > tribehistory.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > tribehistory.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = tribehistory.FetchLimit cfg.Limit = tribehistory.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }

View File

@ -1,12 +0,0 @@
package utils
import "strings"
func FindStringWithPrefix(sl []string, prefix string) string {
for _, s := range sl {
if strings.HasPrefix(s, prefix) {
return s
}
}
return ""
}

View File

@ -1,22 +0,0 @@
package utils
func SafeBoolPointer(value *bool, defaultValue bool) bool {
if value == nil {
return defaultValue
}
return *value
}
func SafeIntPointer(value *int, defaultValue int) int {
if value == nil {
return defaultValue
}
return *value
}
func SafeStrPointer(value *string, defaultValue string) string {
if value == nil {
return defaultValue
}
return *value
}

View File

@ -1,41 +0,0 @@
package utils
import (
"regexp"
"strings"
)
var (
sortexprRegex = regexp.MustCompile(`^[\p{L}\_\.]+$`)
)
func SanitizeSort(expr string) string {
splitted := strings.Split(strings.TrimSpace(expr), " ")
length := len(splitted)
if length != 2 || !sortexprRegex.Match([]byte(splitted[0])) {
return ""
}
table := ""
column := splitted[0]
if strings.Contains(splitted[0], ".") {
columnAndTable := strings.Split(splitted[0], ".")
table = Underscore(columnAndTable[0]) + "."
column = columnAndTable[1]
}
keyword := "ASC"
if strings.ToUpper(splitted[1]) == "DESC" {
keyword = "DESC"
}
return strings.ToLower(table+Underscore(column)) + " " + keyword
}
func SanitizeSorts(sorts []string) []string {
sanitized := []string{}
for _, sort := range sorts {
sanitizedSort := SanitizeSort(sort)
if sanitizedSort != "" {
sanitized = append(sanitized, sanitizedSort)
}
}
return sanitized
}

View File

@ -1,61 +0,0 @@
package utils
import (
"unicode"
"unicode/utf8"
)
type buffer struct {
r []byte
runeBytes [utf8.UTFMax]byte
}
func (b *buffer) write(r rune) {
if r < utf8.RuneSelf {
b.r = append(b.r, byte(r))
return
}
n := utf8.EncodeRune(b.runeBytes[0:], r)
b.r = append(b.r, b.runeBytes[0:n]...)
}
func (b *buffer) indent() {
if len(b.r) > 0 {
b.r = append(b.r, '_')
}
}
func Underscore(s string) string {
b := buffer{
r: make([]byte, 0, len(s)),
}
var m rune
var w bool
for _, ch := range s {
if unicode.IsUpper(ch) {
if m != 0 {
if !w {
b.indent()
w = true
}
b.write(m)
}
m = unicode.ToLower(ch)
} else {
if m != 0 {
b.indent()
b.write(m)
m = 0
w = false
}
b.write(ch)
}
}
if m != 0 {
if !w {
b.indent()
}
b.write(m)
}
return string(b.r)
}

View File

@ -2,12 +2,11 @@ package version
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Filter *models.VersionFilter Filter *twmodel.VersionFilter
Select bool Select bool
Count bool Count bool
Sort []string Sort []string
@ -16,5 +15,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Version, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Version, int, error)
} }

View File

@ -3,12 +3,14 @@ package repository
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/Kichiyaki/gopgutil/v10"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/orm"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tribalwarshelp/api/version" "github.com/tribalwarshelp/api/version"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -16,7 +18,7 @@ type pgRepository struct {
} }
func NewPGRepository(db *pg.DB) (version.Repository, error) { func NewPGRepository(db *pg.DB) (version.Repository, error) {
if err := db.Model(&models.Version{}).CreateTable(&orm.CreateTableOptions{ if err := db.Model(&twmodel.Version{}).CreateTable(&orm.CreateTableOptions{
IfNotExists: true, IfNotExists: true,
}); err != nil { }); err != nil {
return nil, errors.Wrap(err, "cannot create 'versions' table") return nil, errors.Wrap(err, "cannot create 'versions' table")
@ -24,19 +26,20 @@ func NewPGRepository(db *pg.DB) (version.Repository, error) {
return &pgRepository{db}, nil return &pgRepository{db}, nil
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg version.FetchConfig) ([]*models.Version, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg version.FetchConfig) ([]*twmodel.Version, int, error) {
var err error var err error
data := []*models.Version{} data := []*twmodel.Version{}
total := 0 total := 0
query := repo. query := repo.
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Order(cfg.Sort...).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
if cfg.Filter != nil { Apply(cfg.Filter.Where).
query = query.Apply(cfg.Filter.Where) Apply(gopgutil.OrderAppender{
} Orders: cfg.Sort,
MaxDepth: 4,
}.Apply)
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {
total, err = query.SelectAndCount() total, err = query.SelectAndCount()

View File

@ -2,11 +2,10 @@ package version
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Version, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Version, int, error)
GetByCode(ctx context.Context, code models.VersionCode) (*models.Version, error) GetByCode(ctx context.Context, code twmodel.VersionCode) (*twmodel.Version, error)
} }

View File

@ -3,12 +3,10 @@ package usecase
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/api/version" "github.com/tribalwarshelp/api/version"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -21,22 +19,20 @@ func New(repo version.Repository) version.Usecase {
} }
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg version.FetchConfig) ([]*models.Version, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg version.FetchConfig) ([]*twmodel.Version, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.VersionFilter{} cfg.Filter = &twmodel.VersionFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > version.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > version.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = version.FetchLimit cfg.Limit = version.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }
func (ucase *usecase) GetByCode(ctx context.Context, code models.VersionCode) (*models.Version, error) { func (ucase *usecase) GetByCode(ctx context.Context, code twmodel.VersionCode) (*twmodel.Version, error) {
versions, _, err := ucase.repo.Fetch(ctx, version.FetchConfig{ versions, _, err := ucase.repo.Fetch(ctx, version.FetchConfig{
Filter: &models.VersionFilter{ Filter: &twmodel.VersionFilter{
Code: []models.VersionCode{code}, Code: []twmodel.VersionCode{code},
}, },
Limit: 1, Limit: 1,
Select: true, Select: true,

View File

@ -2,13 +2,12 @@ package village
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type FetchConfig struct { type FetchConfig struct {
Server string Server string
Filter *models.VillageFilter Filter *twmodel.VillageFilter
Columns []string Columns []string
Select bool Select bool
Count bool Count bool
@ -18,5 +17,5 @@ type FetchConfig struct {
} }
type Repository interface { type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Village, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Village, int, error)
} }

View File

@ -3,11 +3,13 @@ package repository
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/Kichiyaki/gopgutil/v10"
"github.com/tribalwarshelp/shared/tw/twmodel"
"strings" "strings"
"github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10"
"github.com/tribalwarshelp/api/village" "github.com/tribalwarshelp/api/village"
"github.com/tribalwarshelp/shared/models"
) )
type pgRepository struct { type pgRepository struct {
@ -18,27 +20,23 @@ func NewPGRepository(db *pg.DB) village.Repository {
return &pgRepository{db} return &pgRepository{db}
} }
func (repo *pgRepository) Fetch(ctx context.Context, cfg village.FetchConfig) ([]*models.Village, int, error) { func (repo *pgRepository) Fetch(ctx context.Context, cfg village.FetchConfig) ([]*twmodel.Village, int, error) {
var err error var err error
data := []*models.Village{} data := []*twmodel.Village{}
query := repo. query := repo.
WithParam("SERVER", pg.Safe(cfg.Server)). WithParam("SERVER", pg.Safe(cfg.Server)).
Model(&data). Model(&data).
Context(ctx). Context(ctx).
Limit(cfg.Limit). Limit(cfg.Limit).
Offset(cfg.Offset) Offset(cfg.Offset).
Apply(cfg.Filter.WhereWithRelations).
Apply(gopgutil.OrderAppender{
Orders: cfg.Sort,
MaxDepth: 4,
}.Apply)
if len(cfg.Columns) > 0 { if len(cfg.Columns) > 0 {
query = query.Column(cfg.Columns...) query = query.Column(cfg.Columns...)
} }
relationshipAndSortAppender := &models.VillageRelationshipAndSortAppender{
Filter: &models.VillageFilter{},
Sort: cfg.Sort,
}
if cfg.Filter != nil {
query = query.Apply(cfg.Filter.Where)
relationshipAndSortAppender.Filter = cfg.Filter
}
query = query.Apply(relationshipAndSortAppender.Append)
total := 0 total := 0
if cfg.Count && cfg.Select { if cfg.Count && cfg.Select {

View File

@ -2,11 +2,10 @@ package village
import ( import (
"context" "context"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/shared/models"
) )
type Usecase interface { type Usecase interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Village, int, error) Fetch(ctx context.Context, cfg FetchConfig) ([]*twmodel.Village, int, error)
GetByID(ctx context.Context, server string, id int) (*models.Village, error) GetByID(ctx context.Context, server string, id int) (*twmodel.Village, error)
} }

View File

@ -3,11 +3,10 @@ package usecase
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/tribalwarshelp/shared/tw/twmodel"
"github.com/tribalwarshelp/api/middleware" "github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/api/village" "github.com/tribalwarshelp/api/village"
"github.com/tribalwarshelp/shared/models"
) )
type usecase struct { type usecase struct {
@ -18,21 +17,19 @@ func New(repo village.Repository) village.Usecase {
return &usecase{repo} return &usecase{repo}
} }
func (ucase *usecase) Fetch(ctx context.Context, cfg village.FetchConfig) ([]*models.Village, int, error) { func (ucase *usecase) Fetch(ctx context.Context, cfg village.FetchConfig) ([]*twmodel.Village, int, error) {
if cfg.Filter == nil { if cfg.Filter == nil {
cfg.Filter = &models.VillageFilter{} cfg.Filter = &twmodel.VillageFilter{}
} }
if !middleware.CanExceedLimit(ctx) && (cfg.Limit > village.FetchLimit || cfg.Limit <= 0) { if !middleware.CanExceedLimit(ctx) && (cfg.Limit > village.FetchLimit || cfg.Limit <= 0) {
cfg.Limit = village.FetchLimit cfg.Limit = village.FetchLimit
} }
cfg.Sort = utils.SanitizeSorts(cfg.Sort)
return ucase.repo.Fetch(ctx, cfg) return ucase.repo.Fetch(ctx, cfg)
} }
func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*models.Village, error) { func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*twmodel.Village, error) {
villages, _, err := ucase.repo.Fetch(ctx, village.FetchConfig{ villages, _, err := ucase.repo.Fetch(ctx, village.FetchConfig{
Filter: &models.VillageFilter{ Filter: &twmodel.VillageFilter{
ID: []int{id}, ID: []int{id},
}, },
Limit: 1, Limit: 1,