bump github.com/tribalwarshelp/shared

This commit is contained in:
Dawid Wysokiński 2020-11-06 20:23:12 +01:00
parent ad2f56ad73
commit 00f824e706
30 changed files with 4128 additions and 2711 deletions

6
go.mod
View File

@ -3,7 +3,7 @@ module github.com/tribalwarshelp/api
go 1.14
require (
github.com/99designs/gqlgen v0.11.3
github.com/99designs/gqlgen v0.13.0
github.com/gin-contrib/cors v1.3.1
github.com/gin-gonic/gin v1.6.3
github.com/go-pg/pg/v10 v10.0.0-beta.2
@ -16,8 +16,8 @@ require (
github.com/pkg/errors v0.9.1
github.com/segmentio/encoding v0.1.14 // indirect
github.com/tribalwarshelp/map-generator v0.0.0-20200801113621-fb8892ceb243
github.com/tribalwarshelp/shared v0.0.0-20201031105753-5d4d8b307747
github.com/vektah/gqlparser/v2 v2.0.1
github.com/tribalwarshelp/shared v0.0.0-20201106181031-7c5891c02013
github.com/vektah/gqlparser/v2 v2.1.0
go.opentelemetry.io/otel v0.9.0 // indirect
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect

9
go.sum
View File

@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/99designs/gqlgen v0.11.3 h1:oFSxl1DFS9X///uHV3y6CEfpcXWrDUxVblR4Xib2bs4=
github.com/99designs/gqlgen v0.11.3/go.mod h1:RgX5GRRdDWNkh4pBrdzNpNPFVsdoUFY2+adM6nb1N+4=
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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7 h1:qELHH0AWCvf98Yf+CNIJx9vOZOfHFDDzgDRYsnNk/vs=
@ -107,6 +109,8 @@ github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB
github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
@ -129,6 +133,7 @@ github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdA
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007 h1:reVOUXwnhsYv/8UqjvhrMOu5CNT9UapHFLbQ2JcXsmg=
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@ -195,6 +200,8 @@ github.com/tribalwarshelp/shared v0.0.0-20200622084436-3a768c8bf574 h1:y2EoH6zRK
github.com/tribalwarshelp/shared v0.0.0-20200622084436-3a768c8bf574/go.mod h1:tf+2yTHasV6jAF3V2deZ9slNoCyBzC0fMdTjI7clf6Y=
github.com/tribalwarshelp/shared v0.0.0-20201031105753-5d4d8b307747 h1:ef1VuyVNNxa6ALTPS5X8dPEsAI7KuA3/umNNkrI4fIk=
github.com/tribalwarshelp/shared v0.0.0-20201031105753-5d4d8b307747/go.mod h1:Lxk6zaQhPTPrgz9ksMgg51m8XgflrCo/kRBx2cM3yfk=
github.com/tribalwarshelp/shared v0.0.0-20201106181031-7c5891c02013 h1:6KWK3MWsTfIIWeRfC6+Ba+GvlwbV9Mq+HefbE+QcU2s=
github.com/tribalwarshelp/shared v0.0.0-20201106181031-7c5891c02013/go.mod h1:Lxk6zaQhPTPrgz9ksMgg51m8XgflrCo/kRBx2cM3yfk=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
@ -205,6 +212,8 @@ github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWp
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
github.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o=
github.com/vektah/gqlparser/v2 v2.0.1/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
github.com/vektah/gqlparser/v2 v2.1.0 h1:uiKJ+T5HMGGQM2kRKQ8Pxw8+Zq9qhhZhz/lieYvCMns=
github.com/vektah/gqlparser/v2 v2.1.0/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
github.com/vmihailenco/bufpool v0.1.5/go.mod h1:fL9i/PRTuS7AELqAHwSU1Zf1c70xhkhGe/cD5ud9pJk=
github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94=
github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ=

View File

@ -4,51 +4,51 @@ import (
"context"
"time"
"github.com/tribalwarshelp/api/langversion"
"github.com/tribalwarshelp/api/player"
"github.com/tribalwarshelp/api/tribe"
"github.com/tribalwarshelp/api/version"
"github.com/tribalwarshelp/api/village"
"github.com/tribalwarshelp/shared/models"
)
type DataLoaders struct {
LangVersionByTag LangVersionLoader
VersionByTag VersionLoader
}
type Config struct {
PlayerRepo player.Repository
TribeRepo tribe.Repository
VillageRepo village.Repository
LangVersionRepo langversion.Repository
PlayerRepo player.Repository
TribeRepo tribe.Repository
VillageRepo village.Repository
VersionRepo version.Repository
}
func NewDataLoaders(cfg Config) *DataLoaders {
return &DataLoaders{
LangVersionByTag: LangVersionLoader{
VersionByTag: VersionLoader{
wait: 2 * time.Millisecond,
maxBatch: 0,
fetch: func(keys []string) ([]*models.LangVersion, []error) {
tags := []models.LanguageTag{}
for _, tag := range keys {
tags = append(tags, models.LanguageTag(tag))
fetch: func(keys []string) ([]*models.Version, []error) {
codes := []models.VersionCode{}
for _, code := range keys {
codes = append(codes, models.VersionCode(code))
}
langVersions, _, err := cfg.LangVersionRepo.Fetch(context.Background(), langversion.FetchConfig{
Filter: &models.LangVersionFilter{
Tag: tags,
versions, _, err := cfg.VersionRepo.Fetch(context.Background(), version.FetchConfig{
Filter: &models.VersionFilter{
Code: codes,
},
})
if err != nil {
return nil, []error{err}
}
langVersionByTag := make(map[models.LanguageTag]*models.LangVersion)
for _, langVersion := range langVersions {
langVersionByTag[langVersion.Tag] = langVersion
versionByCode := make(map[models.VersionCode]*models.Version)
for _, version := range versions {
versionByCode[version.Code] = version
}
inOrder := make([]*models.LangVersion, len(keys))
for i, tag := range tags {
inOrder[i] = langVersionByTag[tag]
inOrder := make([]*models.Version, len(keys))
for i, code := range codes {
inOrder[i] = versionByCode[code]
}
return inOrder, nil

View File

@ -7,18 +7,18 @@ import (
"github.com/tribalwarshelp/shared/models"
)
type LangVersionDataLoaders struct {
type VersionDataLoaders struct {
PlayerServersByID PlayerServersLoader
PlayerNameChangesByID PlayerNameChangesLoader
}
func NewLangVersionDataLoaders(langTag models.LanguageTag, cfg Config) *LangVersionDataLoaders {
return &LangVersionDataLoaders{
func NewVersionDataLoaders(versionCode models.VersionCode, cfg Config) *VersionDataLoaders {
return &VersionDataLoaders{
PlayerServersByID: PlayerServersLoader{
wait: 2 * time.Millisecond,
maxBatch: 0,
fetch: func(keys []int) ([][]string, []error) {
playerServersByID, err := cfg.PlayerRepo.FetchPlayerServers(context.Background(), langTag, keys...)
playerServersByID, err := cfg.PlayerRepo.FetchPlayerServers(context.Background(), versionCode, keys...)
if err != nil {
return nil, []error{err}
}
@ -33,7 +33,7 @@ func NewLangVersionDataLoaders(langTag models.LanguageTag, cfg Config) *LangVers
wait: 2 * time.Millisecond,
maxBatch: 0,
fetch: func(keys []int) ([][]*models.PlayerNameChange, []error) {
playerNameChangesByID, err := cfg.PlayerRepo.FetchNameChanges(context.Background(), langTag, keys...)
playerNameChangesByID, err := cfg.PlayerRepo.FetchNameChanges(context.Background(), versionCode, keys...)
if err != nil {
return nil, []error{err}
}

View File

@ -9,10 +9,10 @@ import (
"github.com/tribalwarshelp/shared/models"
)
// LangVersionLoaderConfig captures the config to create a new LangVersionLoader
type LangVersionLoaderConfig struct {
// VersionLoaderConfig captures the config to create a new VersionLoader
type VersionLoaderConfig struct {
// Fetch is a method that provides the data for the loader
Fetch func(keys []string) ([]*models.LangVersion, []error)
Fetch func(keys []string) ([]*models.Version, []error)
// Wait is how long wait before sending a batch
Wait time.Duration
@ -21,19 +21,19 @@ type LangVersionLoaderConfig struct {
MaxBatch int
}
// NewLangVersionLoader creates a new LangVersionLoader given a fetch, wait, and maxBatch
func NewLangVersionLoader(config LangVersionLoaderConfig) *LangVersionLoader {
return &LangVersionLoader{
// NewVersionLoader creates a new VersionLoader given a fetch, wait, and maxBatch
func NewVersionLoader(config VersionLoaderConfig) *VersionLoader {
return &VersionLoader{
fetch: config.Fetch,
wait: config.Wait,
maxBatch: config.MaxBatch,
}
}
// LangVersionLoader batches and caches requests
type LangVersionLoader struct {
// VersionLoader batches and caches requests
type VersionLoader struct {
// this method provides the data for the loader
fetch func(keys []string) ([]*models.LangVersion, []error)
fetch func(keys []string) ([]*models.Version, []error)
// how long to done before sending a batch
wait time.Duration
@ -44,51 +44,51 @@ type LangVersionLoader struct {
// INTERNAL
// lazily created cache
cache map[string]*models.LangVersion
cache map[string]*models.Version
// 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
batch *langVersionLoaderBatch
batch *versionLoaderBatch
// mutex to prevent races
mu sync.Mutex
}
type langVersionLoaderBatch struct {
type versionLoaderBatch struct {
keys []string
data []*models.LangVersion
data []*models.Version
error []error
closing bool
done chan struct{}
}
// Load a LangVersion by key, batching and caching will be applied automatically
func (l *LangVersionLoader) Load(key string) (*models.LangVersion, error) {
// Load a Version by key, batching and caching will be applied automatically
func (l *VersionLoader) Load(key string) (*models.Version, error) {
return l.LoadThunk(key)()
}
// LoadThunk returns a function that when called will block waiting for a LangVersion.
// 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
// different data loaders without blocking until the thunk is called.
func (l *LangVersionLoader) LoadThunk(key string) func() (*models.LangVersion, error) {
func (l *VersionLoader) LoadThunk(key string) func() (*models.Version, error) {
l.mu.Lock()
if it, ok := l.cache[key]; ok {
l.mu.Unlock()
return func() (*models.LangVersion, error) {
return func() (*models.Version, error) {
return it, nil
}
}
if l.batch == nil {
l.batch = &langVersionLoaderBatch{done: make(chan struct{})}
l.batch = &versionLoaderBatch{done: make(chan struct{})}
}
batch := l.batch
pos := batch.keyIndex(l, key)
l.mu.Unlock()
return func() (*models.LangVersion, error) {
return func() (*models.Version, error) {
<-batch.done
var data *models.LangVersion
var data *models.Version
if pos < len(batch.data) {
data = batch.data[pos]
}
@ -113,43 +113,43 @@ func (l *LangVersionLoader) LoadThunk(key string) func() (*models.LangVersion, e
// LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured
func (l *LangVersionLoader) LoadAll(keys []string) ([]*models.LangVersion, []error) {
results := make([]func() (*models.LangVersion, error), len(keys))
func (l *VersionLoader) LoadAll(keys []string) ([]*models.Version, []error) {
results := make([]func() (*models.Version, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
langVersions := make([]*models.LangVersion, len(keys))
versions := make([]*models.Version, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
langVersions[i], errors[i] = thunk()
versions[i], errors[i] = thunk()
}
return langVersions, errors
return versions, errors
}
// LoadAllThunk returns a function that when called will block waiting for a LangVersions.
// 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
// different data loaders without blocking until the thunk is called.
func (l *LangVersionLoader) LoadAllThunk(keys []string) func() ([]*models.LangVersion, []error) {
results := make([]func() (*models.LangVersion, error), len(keys))
func (l *VersionLoader) LoadAllThunk(keys []string) func() ([]*models.Version, []error) {
results := make([]func() (*models.Version, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
return func() ([]*models.LangVersion, []error) {
langVersions := make([]*models.LangVersion, len(keys))
return func() ([]*models.Version, []error) {
versions := make([]*models.Version, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
langVersions[i], errors[i] = thunk()
versions[i], errors[i] = thunk()
}
return langVersions, errors
return versions, errors
}
}
// Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *LangVersionLoader) Prime(key string, value *models.LangVersion) bool {
func (l *VersionLoader) Prime(key string, value *models.Version) bool {
l.mu.Lock()
var found bool
if _, found = l.cache[key]; !found {
@ -163,22 +163,22 @@ func (l *LangVersionLoader) Prime(key string, value *models.LangVersion) bool {
}
// Clear the value at key from the cache, if it exists
func (l *LangVersionLoader) Clear(key string) {
func (l *VersionLoader) Clear(key string) {
l.mu.Lock()
delete(l.cache, key)
l.mu.Unlock()
}
func (l *LangVersionLoader) unsafeSet(key string, value *models.LangVersion) {
func (l *VersionLoader) unsafeSet(key string, value *models.Version) {
if l.cache == nil {
l.cache = map[string]*models.LangVersion{}
l.cache = map[string]*models.Version{}
}
l.cache[key] = value
}
// keyIndex will return the location of the key in the batch, if its not found
// it will add the key to the batch
func (b *langVersionLoaderBatch) keyIndex(l *LangVersionLoader, key string) int {
func (b *versionLoaderBatch) keyIndex(l *VersionLoader, key string) int {
for i, existingKey := range b.keys {
if key == existingKey {
return i
@ -202,7 +202,7 @@ func (b *langVersionLoaderBatch) keyIndex(l *LangVersionLoader, key string) int
return pos
}
func (b *langVersionLoaderBatch) startTimer(l *LangVersionLoader) {
func (b *versionLoaderBatch) startTimer(l *VersionLoader) {
time.Sleep(l.wait)
l.mu.Lock()
@ -218,7 +218,7 @@ func (b *langVersionLoaderBatch) startTimer(l *LangVersionLoader) {
b.end(l)
}
func (b *langVersionLoaderBatch) end(l *LangVersionLoader) {
func (b *versionLoaderBatch) end(l *VersionLoader) {
b.data, b.error = l.fetch(b.keys)
close(b.done)
}

File diff suppressed because it is too large Load Diff

View File

@ -21,11 +21,6 @@ type EnnoblementList struct {
Total int `json:"total"`
}
type LangVersionList struct {
Items []*models.LangVersion `json:"items"`
Total int `json:"total"`
}
type PlayerHistory struct {
Total int `json:"total"`
Items []*models.PlayerHistory `json:"items"`
@ -61,6 +56,11 @@ type TribeList struct {
Total int `json:"total"`
}
type VersionList struct {
Items []*models.Version `json:"items"`
Total int `json:"total"`
}
type VillageList struct {
Items []*models.Village `json:"items"`
Total int `json:"total"`

View File

@ -11,15 +11,18 @@ resolver:
package: resolvers
type: Resolver
struct_tag: gqlgen
directives:
deprecated:
skip_runtime: true
models:
LanguageTag:
model: github.com/tribalwarshelp/shared/models.LanguageTag
VersionCode:
model: github.com/tribalwarshelp/shared/models.VersionCode
ServerStatus:
model: github.com/tribalwarshelp/shared/models.ServerStatus
LangVersion:
model: github.com/tribalwarshelp/shared/models.LangVersion
LangVersionFilter:
model: github.com/tribalwarshelp/shared/models.LangVersionFilter
Version:
model: github.com/tribalwarshelp/shared/models.Version
VersionFilter:
model: github.com/tribalwarshelp/shared/models.VersionFilter
Server:
model: github.com/tribalwarshelp/shared/models.Server
ServerConfig:

View File

@ -1,19 +0,0 @@
package resolvers
import (
"context"
"github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/shared/models"
)
func (r *queryResolver) LangVersions(ctx context.Context, filter *models.LangVersionFilter) (*generated.LangVersionList, error) {
var err error
list := &generated.LangVersionList{}
list.Items, list.Total, err = r.LangVersionUcase.Fetch(ctx, filter)
return list, err
}
func (r *queryResolver) LangVersion(ctx context.Context, tag models.LanguageTag) (*models.LangVersion, error) {
return r.LangVersionUcase.GetByTag(ctx, tag)
}

View File

@ -18,10 +18,10 @@ func (r *playerResolver) Tribe(ctx context.Context, obj *models.Player) (*models
}
func (r *playerResolver) Servers(ctx context.Context, obj *models.Player) ([]string, error) {
langVersionDataLoaders := middleware.LangVersionDataLoadersFromContext(ctx)
if langVersionDataLoaders != nil {
versionDataLoaders := middleware.VersionDataLoadersFromContext(ctx)
if versionDataLoaders != nil {
serverKey, _ := getServer(ctx)
if loaders, ok := langVersionDataLoaders[tw.LanguageTagFromServerKey(serverKey)]; ok {
if loaders, ok := versionDataLoaders[tw.VersionCodeFromServerKey(serverKey)]; ok {
servers, err := loaders.PlayerServersByID.Load(obj.ID)
if err == nil {
return servers, nil
@ -32,10 +32,10 @@ func (r *playerResolver) Servers(ctx context.Context, obj *models.Player) ([]str
}
func (r *playerResolver) NameChanges(ctx context.Context, obj *models.Player) ([]*models.PlayerNameChange, error) {
langVersionDataLoaders := middleware.LangVersionDataLoadersFromContext(ctx)
if langVersionDataLoaders != nil {
versionDataLoaders := middleware.VersionDataLoadersFromContext(ctx)
if versionDataLoaders != nil {
serverKey, _ := getServer(ctx)
if loaders, ok := langVersionDataLoaders[tw.LanguageTagFromServerKey(serverKey)]; ok {
if loaders, ok := versionDataLoaders[tw.VersionCodeFromServerKey(serverKey)]; ok {
servers, err := loaders.PlayerNameChangesByID.Load(obj.ID)
if err == nil {
return servers, nil

View File

@ -5,7 +5,6 @@ import (
"github.com/tribalwarshelp/api/dailytribestats"
"github.com/tribalwarshelp/api/ennoblement"
"github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/langversion"
"github.com/tribalwarshelp/api/liveennoblement"
"github.com/tribalwarshelp/api/player"
"github.com/tribalwarshelp/api/playerhistory"
@ -14,11 +13,12 @@ import (
"github.com/tribalwarshelp/api/tribe"
"github.com/tribalwarshelp/api/tribechange"
"github.com/tribalwarshelp/api/tribehistory"
"github.com/tribalwarshelp/api/version"
"github.com/tribalwarshelp/api/village"
)
type Resolver struct {
LangVersionUcase langversion.Usecase
VersionUcase version.Usecase
ServerUcase server.Usecase
PlayerUcase player.Usecase
TribeUcase tribe.Usecase
@ -57,6 +57,9 @@ func (r *Resolver) DailyPlayerStatsRecord() generated.DailyPlayerStatsRecordReso
func (r *Resolver) DailyTribeStatsRecord() generated.DailyTribeStatsRecordResolver {
return &dailyTribeStatsRecordResolver{r}
}
func (r *Resolver) Version() generated.VersionResolver {
return &versionResolver{r}
}
type queryResolver struct{ *Resolver }
type playerResolver struct{ *Resolver }
@ -71,3 +74,4 @@ type serverStatsRecordResolver struct{ *Resolver }
type tribeChangeRecordResolver struct{ *Resolver }
type dailyPlayerStatsRecordResolver struct{ *Resolver }
type dailyTribeStatsRecordResolver struct{ *Resolver }
type versionResolver struct{ *Resolver }

View File

@ -9,15 +9,19 @@ import (
"github.com/tribalwarshelp/shared/models"
)
func (r *serverResolver) LangVersion(ctx context.Context, obj *models.Server) (*models.LangVersion, error) {
func (r *serverResolver) Version(ctx context.Context, obj *models.Server) (*models.Version, error) {
loaders := middleware.DataLoadersFromContext(ctx)
if loaders != nil {
lv, _ := loaders.LangVersionByTag.Load(obj.LangVersionTag.String())
lv, _ := loaders.VersionByTag.Load(obj.VersionCode.String())
return lv, nil
}
return nil, nil
}
func (r *serverResolver) LangVersion(ctx context.Context, obj *models.Server) (*models.Version, error) {
return r.Version(ctx, obj)
}
func (r *queryResolver) Servers(ctx context.Context, filter *models.ServerFilter) (*generated.ServerList, error) {
var err error
list := &generated.ServerList{}

View File

@ -0,0 +1,31 @@
package resolvers
import (
"context"
"github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/shared/models"
)
func (r *versionResolver) Tag(ctx context.Context, obj *models.Version) (models.VersionCode, error) {
return obj.Code, nil
}
func (r *queryResolver) Versions(ctx context.Context, filter *models.VersionFilter) (*generated.VersionList, error) {
var err error
list := &generated.VersionList{}
list.Items, list.Total, err = r.VersionUcase.Fetch(ctx, filter)
return list, err
}
func (r *queryResolver) Version(ctx context.Context, code models.VersionCode) (*models.Version, error) {
return r.VersionUcase.GetByCode(ctx, code)
}
func (r *queryResolver) LangVersions(ctx context.Context, filter *models.VersionFilter) (*generated.VersionList, error) {
return r.Versions(ctx, filter)
}
func (r *queryResolver) LangVersion(ctx context.Context, tag models.VersionCode) (*models.Version, error) {
return r.Version(ctx, tag)
}

View File

@ -2,3 +2,5 @@ directive @goField(
forceResolver: Boolean
name: String
) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
directive @depreacted(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE

View File

@ -1,51 +0,0 @@
enum LanguageTag {
PL
EN
DE
UK
IT
FR
US
NL
ES
RO
RU
GR
TR
CS
CH
PT
BR
HU
}
type LangVersion {
tag: LanguageTag!
name: String!
host: String!
timezone: String!
}
input LangVersionFilter {
tag: [LanguageTag!]
tagNEQ: [LanguageTag!]
host: [String!]
hostNEQ: [String!]
hostMATCH: String
hostIEQ: String
offset: Int
limit: Int
sort: String
}
type LangVersionList {
items: [LangVersion!]
total: Int!
}
extend type Query {
langVersions(filter: LangVersionFilter): LangVersionList!
langVersion(tag: LanguageTag!): LangVersion
}

View File

@ -10,7 +10,8 @@ type Server {
numberOfTribes: Int!
numberOfVillages: Int!
langVersion: LangVersion @goField(forceResolver: true)
langVersion: Version @goField(forceResolver: true) @depreacted(reason: "Renamed to version")
version: Version @goField(forceResolver: true)
config: ServerConfig!
unitConfig: UnitConfig!
@ -35,8 +36,10 @@ input ServerFilter {
status: [ServerStatus!]
statusNEQ: [ServerStatus!]
langVersionTag: [LanguageTag!]
langVersionTagNEQ: [LanguageTag!]
langVersionTag: [VersionCode!] @depreacted
langVersionTagNEQ: [VersionCode!] @depreacted
versionCode: [VersionCode!]
versionCodeNEQ: [VersionCode!]
offset: Int
limit: Int

View File

@ -0,0 +1,57 @@
enum VersionCode {
PL
EN
DE
UK
IT
FR
US
NL
ES
RO
RU
GR
TR
CS
CH
PT
BR
HU
}
type Version {
tag: VersionCode! @depreacted @goField(forceResolver: true)
code: VersionCode!
name: String!
host: String!
timezone: String!
}
input VersionFilter {
languageTag: [VersionCode!] @depreacted
languageTagNEQ: [VersionCode!] @depreacted
code: [VersionCode!]
codeNEQ: [VersionCode!]
host: [String!]
hostNEQ: [String!]
hostMATCH: String
hostIEQ: String
offset: Int
limit: Int
sort: String
}
type VersionList {
items: [Version!]
total: Int!
}
extend type Query {
langVersions(filter: VersionFilter): VersionList! @depreacted @goField(forceResolver: true)
langVersion(tag: VersionCode!): Version @depreacted @goField(forceResolver: true)
versions(filter: VersionFilter): VersionList!
version(code: VersionCode!): Version
}

View File

@ -1,12 +0,0 @@
package langversion
import (
"context"
"github.com/tribalwarshelp/shared/models"
)
type Usecase interface {
Fetch(ctx context.Context, filter *models.LangVersionFilter) ([]*models.LangVersion, int, error)
GetByTag(ctx context.Context, tag models.LanguageTag) (*models.LangVersion, error)
}

View File

@ -1,52 +0,0 @@
package usecase
import (
"context"
"fmt"
"github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/api/langversion"
"github.com/tribalwarshelp/shared/models"
)
type usecase struct {
repo langversion.Repository
}
func New(repo langversion.Repository) langversion.Usecase {
return &usecase{
repo,
}
}
func (ucase *usecase) Fetch(ctx context.Context, filter *models.LangVersionFilter) ([]*models.LangVersion, int, error) {
if filter == nil {
filter = &models.LangVersionFilter{}
}
if !middleware.MayExceedLimit(ctx) && (filter.Limit > langversion.PaginationLimit || filter.Limit <= 0) {
filter.Limit = langversion.PaginationLimit
}
filter.Sort = utils.SanitizeSort(filter.Sort)
return ucase.repo.Fetch(ctx, langversion.FetchConfig{
Filter: filter,
Count: true,
})
}
func (ucase *usecase) GetByTag(ctx context.Context, tag models.LanguageTag) (*models.LangVersion, error) {
langversions, _, err := ucase.repo.Fetch(ctx, langversion.FetchConfig{
Filter: &models.LangVersionFilter{
Tag: []models.LanguageTag{tag},
Limit: 1,
},
})
if err != nil {
return nil, err
}
if len(langversions) == 0 {
return nil, fmt.Errorf("There is no lang version with tag: %s.", tag)
}
return langversions[0], nil
}

View File

@ -36,7 +36,7 @@ func (repo *pgRepository) Fetch(ctx context.Context, server string) ([]*models.L
}
s := &models.Server{}
if err := repo.Model(s).Where("key = ?", server).Relation("LangVersion").Select(); err != nil {
if err := repo.Model(s).Where("key = ?", server).Relation("Version").Select(); err != nil {
if err == pg.ErrNoRows {
return nil, fmt.Errorf("Server not found")
}
@ -49,7 +49,7 @@ func (repo *pgRepository) Fetch(ctx context.Context, server string) ([]*models.L
}
dl := dataloader.New(&dataloader.Config{
BaseURL: "https://" + s.Key + "." + s.LangVersion.Host,
BaseURL: "https://" + s.Key + "." + s.Version.Host,
})
ennoblements, err := dl.LoadEnnoblements(&dataloader.LoadEnnoblementsConfig{
EnnobledAtGTE: time.Now().Add(-1 * time.Hour),

16
main.go
View File

@ -27,8 +27,6 @@ import (
dailytribestatsucase "github.com/tribalwarshelp/api/dailytribestats/usecase"
ennoblementrepo "github.com/tribalwarshelp/api/ennoblement/repository"
ennoblementucase "github.com/tribalwarshelp/api/ennoblement/usecase"
langversionrepo "github.com/tribalwarshelp/api/langversion/repository"
langversionucase "github.com/tribalwarshelp/api/langversion/usecase"
liveennoblementrepo "github.com/tribalwarshelp/api/liveennoblement/repository"
liveennoblementucase "github.com/tribalwarshelp/api/liveennoblement/usecase"
"github.com/tribalwarshelp/api/middleware"
@ -47,6 +45,8 @@ import (
tribechangeucase "github.com/tribalwarshelp/api/tribechange/usecase"
tribehistoryrepo "github.com/tribalwarshelp/api/tribehistory/repository"
tribehistoryucase "github.com/tribalwarshelp/api/tribehistory/usecase"
versionrepo "github.com/tribalwarshelp/api/version/repository"
versionucase "github.com/tribalwarshelp/api/version/usecase"
villagerepo "github.com/tribalwarshelp/api/village/repository"
villageucase "github.com/tribalwarshelp/api/village/usecase"
@ -96,7 +96,7 @@ func main() {
}
}()
langversionRepo, err := langversionrepo.NewPGRepository(db)
versionRepo, err := versionrepo.NewPGRepository(db)
if err != nil {
log.Fatal(err)
}
@ -142,10 +142,10 @@ func main() {
ServerRepo: serverRepo,
},
dataloaders.Config{
PlayerRepo: playerRepo,
TribeRepo: tribeRepo,
VillageRepo: villageRepo,
LangVersionRepo: langversionRepo,
PlayerRepo: playerRepo,
TribeRepo: tribeRepo,
VillageRepo: villageRepo,
VersionRepo: versionRepo,
}))
graphql.Use(middleware.LimitWhitelist(middleware.LimitWhitelistConfig{
IPAddresses: strings.Split(os.Getenv("LIMIT_WHITELIST"), ","),
@ -153,7 +153,7 @@ func main() {
httpdelivery.Attach(httpdelivery.Config{
RouterGroup: graphql,
Resolver: &resolvers.Resolver{
LangVersionUcase: langversionucase.New(langversionRepo),
VersionUcase: versionucase.New(versionRepo),
ServerUcase: serverUcase,
TribeUcase: tribeucase.New(tribeRepo),
PlayerUcase: playerucase.New(playerRepo),

View File

@ -15,7 +15,7 @@ import (
)
var serverDataLoadersContextKey ContextKey = "serverDataLoaders"
var langVersionLoadersContextKey ContextKey = "langVersionLoaders"
var versionLoadersContextKey ContextKey = "versionLoaders"
var dataloadersContextKey ContextKey = "dataloaders"
type DataLoadersToContextConfig struct {
@ -26,9 +26,9 @@ func DataLoadersToContext(dltcc DataLoadersToContextConfig, cfg dataloaders.Conf
return func(c *gin.Context) {
ctx := c.Request.Context()
serverDataLoaders := make(map[string]*dataloaders.ServerDataLoaders)
langVersionDataLoaders := make(map[models.LanguageTag]*dataloaders.LangVersionDataLoaders)
versionDataLoaders := make(map[models.VersionCode]*dataloaders.VersionDataLoaders)
servers, _, err := dltcc.ServerRepo.Fetch(c.Request.Context(), server.FetchConfig{
Columns: []string{utils.Underscore("langVersionTag"), "key"},
Columns: []string{utils.Underscore("versionCode"), "key"},
})
if err != nil {
c.JSON(http.StatusOK, &gqlerror.Error{
@ -39,12 +39,12 @@ func DataLoadersToContext(dltcc DataLoadersToContextConfig, cfg dataloaders.Conf
}
for _, server := range servers {
serverDataLoaders[server.Key] = dataloaders.NewServerDataLoaders(server.Key, cfg)
if _, ok := langVersionDataLoaders[server.LangVersionTag]; !ok {
langVersionDataLoaders[server.LangVersionTag] = dataloaders.NewLangVersionDataLoaders(server.LangVersionTag, cfg)
if _, ok := versionDataLoaders[server.VersionCode]; !ok {
versionDataLoaders[server.VersionCode] = dataloaders.NewVersionDataLoaders(server.VersionCode, cfg)
}
}
ctx = StoreServerDataLoadersInContext(ctx, serverDataLoaders)
ctx = StoreLangVersionDataLoadersInContext(ctx, langVersionDataLoaders)
ctx = StoreVersionDataLoadersInContext(ctx, versionDataLoaders)
ctx = StoreDataLoadersInContext(ctx, dataloaders.NewDataLoaders(cfg))
c.Request = c.Request.WithContext(ctx)
c.Next()
@ -64,17 +64,17 @@ func ServerDataLoadersFromContext(ctx context.Context) map[string]*dataloaders.S
return dl.(map[string]*dataloaders.ServerDataLoaders)
}
func StoreLangVersionDataLoadersInContext(ctx context.Context, loaders map[models.LanguageTag]*dataloaders.LangVersionDataLoaders) context.Context {
return context.WithValue(ctx, langVersionLoadersContextKey, loaders)
func StoreVersionDataLoadersInContext(ctx context.Context, loaders map[models.VersionCode]*dataloaders.VersionDataLoaders) context.Context {
return context.WithValue(ctx, versionLoadersContextKey, loaders)
}
func LangVersionDataLoadersFromContext(ctx context.Context) map[models.LanguageTag]*dataloaders.LangVersionDataLoaders {
dl := ctx.Value(langVersionLoadersContextKey)
func VersionDataLoadersFromContext(ctx context.Context) map[models.VersionCode]*dataloaders.VersionDataLoaders {
dl := ctx.Value(versionLoadersContextKey)
if dl == nil {
return nil
}
return dl.(map[models.LanguageTag]*dataloaders.LangVersionDataLoaders)
return dl.(map[models.VersionCode]*dataloaders.VersionDataLoaders)
}
func StoreDataLoadersInContext(ctx context.Context, loaders *dataloaders.DataLoaders) context.Context {

View File

@ -14,6 +14,6 @@ type FetchConfig struct {
type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Player, int, error)
FetchNameChanges(ctx context.Context, langTag models.LanguageTag, playerID ...int) (map[int][]*models.PlayerNameChange, error)
FetchPlayerServers(ctx context.Context, langTag models.LanguageTag, playerID ...int) (map[int][]string, error)
FetchNameChanges(ctx context.Context, code models.VersionCode, playerID ...int) (map[int][]*models.PlayerNameChange, error)
FetchPlayerServers(ctx context.Context, code models.VersionCode, playerID ...int) (map[int][]string, error)
}

View File

@ -72,11 +72,11 @@ type fetchPlayerServersQueryResult struct {
Servers []string `pg:",array"`
}
func (repo *pgRepository) FetchNameChanges(ctx context.Context, langTag models.LanguageTag, playerID ...int) (map[int][]*models.PlayerNameChange, error) {
func (repo *pgRepository) FetchNameChanges(ctx context.Context, code models.VersionCode, playerID ...int) (map[int][]*models.PlayerNameChange, error) {
data := []*models.PlayerNameChange{}
if err := repo.Model(&data).
Context(ctx).
Where("lang_version_tag = ?", langTag).
Where("version_code = ?", code).
Where("player_id IN (?)", pg.In(playerID)).
Select(); err != nil && err != pg.ErrNoRows {
return nil, errors.Wrap(err, "Internal server error")
@ -89,14 +89,14 @@ func (repo *pgRepository) FetchNameChanges(ctx context.Context, langTag models.L
return m, nil
}
func (repo *pgRepository) FetchPlayerServers(ctx context.Context, langTag models.LanguageTag, playerID ...int) (map[int][]string, error) {
func (repo *pgRepository) FetchPlayerServers(ctx context.Context, code models.VersionCode, playerID ...int) (map[int][]string, error) {
data := []*fetchPlayerServersQueryResult{}
if err := repo.Model(&models.PlayerToServer{}).
Context(ctx).
Column("player_id").
ColumnExpr("array_agg(server_key) as servers").
Relation("Server._").
Where("lang_version_tag = ?", langTag).
Where("version_code = ?", code).
Where("player_id IN (?)", pg.In(playerID)).
Group("player_id").
Select(&data); err != nil && err != pg.ErrNoRows {

View File

@ -25,6 +25,12 @@ func (ucase *usecase) Fetch(ctx context.Context, filter *models.ServerFilter) ([
if !middleware.MayExceedLimit(ctx) && (filter.Limit > server.PaginationLimit || filter.Limit <= 0) {
filter.Limit = server.PaginationLimit
}
if len(filter.LangVersionTag) > 0 {
filter.VersionCode = append(filter.VersionCode, filter.LangVersionTag...)
}
if len(filter.LangVersionTagNEQ) > 0 {
filter.VersionCodeNEQ = append(filter.VersionCode, filter.LangVersionTagNEQ...)
}
filter.Sort = utils.SanitizeSort(filter.Sort)
return ucase.repo.Fetch(ctx, server.FetchConfig{
Count: true,

View File

@ -1,4 +1,4 @@
package langversion
package version
const (
PaginationLimit = 100

View File

@ -1,4 +1,4 @@
package langversion
package version
import (
"context"
@ -7,10 +7,10 @@ import (
)
type FetchConfig struct {
Filter *models.LangVersionFilter
Filter *models.VersionFilter
Count bool
}
type Repository interface {
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.LangVersion, int, error)
Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Version, int, error)
}

View File

@ -6,7 +6,7 @@ import (
"github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm"
"github.com/pkg/errors"
"github.com/tribalwarshelp/api/langversion"
"github.com/tribalwarshelp/api/version"
"github.com/tribalwarshelp/shared/models"
)
@ -14,18 +14,18 @@ type pgRepository struct {
*pg.DB
}
func NewPGRepository(db *pg.DB) (langversion.Repository, error) {
if err := db.CreateTable((*models.LangVersion)(nil), &orm.CreateTableOptions{
func NewPGRepository(db *pg.DB) (version.Repository, error) {
if err := db.CreateTable((*models.Version)(nil), &orm.CreateTableOptions{
IfNotExists: true,
}); err != nil {
return nil, errors.Wrap(err, "Cannot create 'lang_versions' table")
return nil, errors.Wrap(err, "Cannot create 'versions' table")
}
return &pgRepository{db}, nil
}
func (repo *pgRepository) Fetch(ctx context.Context, cfg langversion.FetchConfig) ([]*models.LangVersion, int, error) {
func (repo *pgRepository) Fetch(ctx context.Context, cfg version.FetchConfig) ([]*models.Version, int, error) {
var err error
data := []*models.LangVersion{}
data := []*models.Version{}
total := 0
query := repo.Model(&data).Context(ctx)

12
version/usecase.go Normal file
View File

@ -0,0 +1,12 @@
package version
import (
"context"
"github.com/tribalwarshelp/shared/models"
)
type Usecase interface {
Fetch(ctx context.Context, filter *models.VersionFilter) ([]*models.Version, int, error)
GetByCode(ctx context.Context, code models.VersionCode) (*models.Version, error)
}

View File

@ -0,0 +1,58 @@
package usecase
import (
"context"
"fmt"
"github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/api/version"
"github.com/tribalwarshelp/shared/models"
)
type usecase struct {
repo version.Repository
}
func New(repo version.Repository) version.Usecase {
return &usecase{
repo,
}
}
func (ucase *usecase) Fetch(ctx context.Context, filter *models.VersionFilter) ([]*models.Version, int, error) {
if filter == nil {
filter = &models.VersionFilter{}
}
if !middleware.MayExceedLimit(ctx) && (filter.Limit > version.PaginationLimit || filter.Limit <= 0) {
filter.Limit = version.PaginationLimit
}
if len(filter.LanguageTag) > 0 {
filter.Code = append(filter.Code, filter.LanguageTag...)
}
if len(filter.LanguageTagNEQ) > 0 {
filter.CodeNEQ = append(filter.Code, filter.LanguageTagNEQ...)
}
filter.Sort = utils.SanitizeSort(filter.Sort)
return ucase.repo.Fetch(ctx, version.FetchConfig{
Filter: filter,
Count: true,
})
}
func (ucase *usecase) GetByCode(ctx context.Context, code models.VersionCode) (*models.Version, error) {
versions, _, err := ucase.repo.Fetch(ctx, version.FetchConfig{
Filter: &models.VersionFilter{
Code: []models.VersionCode{code},
Limit: 1,
},
})
if err != nil {
return nil, err
}
if len(versions) == 0 {
return nil, fmt.Errorf("There is no version with code: %s.", code)
}
return versions[0], nil
}