bump github.com/tribalwarshelp/shared, add 2 new fields to Player graphql type: deletedAt and nameChanges, add 1 new field to Tribe graphql type: deletedAt

This commit is contained in:
Dawid Wysokiński 2020-06-24 16:40:29 +02:00
parent ebc2b95002
commit df771d0503
11 changed files with 753 additions and 11 deletions

2
go.mod
View File

@ -14,7 +14,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/segmentio/encoding v0.1.14 // indirect
github.com/tribalwarshelp/map-generator v0.0.0-20200623143352-cc037d744be2
github.com/tribalwarshelp/shared v0.0.0-20200624131453-e04f1de1bf5c
github.com/tribalwarshelp/shared v0.0.0-20200624134544-636239c5fd17
github.com/vektah/gqlparser/v2 v2.0.1
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect

3
go.sum
View File

@ -179,12 +179,15 @@ github.com/tribalwarshelp/shared v0.0.0-20200623144748-aa834a01dce6 h1:WZ1oxHysF
github.com/tribalwarshelp/shared v0.0.0-20200623144748-aa834a01dce6/go.mod h1:tf+2yTHasV6jAF3V2deZ9slNoCyBzC0fMdTjI7clf6Y=
github.com/tribalwarshelp/shared v0.0.0-20200624131453-e04f1de1bf5c h1:sPu2tYRqZYAFwhJtZ4cDWLwanauQ4+4zlGEgdQNrVn4=
github.com/tribalwarshelp/shared v0.0.0-20200624131453-e04f1de1bf5c/go.mod h1:tf+2yTHasV6jAF3V2deZ9slNoCyBzC0fMdTjI7clf6Y=
github.com/tribalwarshelp/shared v0.0.0-20200624134544-636239c5fd17 h1:DUMz3ROe2nYRszZuu97LVIgdPrt8QBWAVouFlrucL8c=
github.com/tribalwarshelp/shared v0.0.0-20200624134544-636239c5fd17/go.mod h1:tf+2yTHasV6jAF3V2deZ9slNoCyBzC0fMdTjI7clf6Y=
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=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg=
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=

View File

@ -8,7 +8,8 @@ import (
)
type LangVersionDataLoaders struct {
PlayerServersByID PlayerServersLoader
PlayerServersByID PlayerServersLoader
PlayerNameChangesByID PlayerNameChangesLoader
}
func NewLangVersionDataLoaders(langTag models.LanguageTag, cfg Config) *LangVersionDataLoaders {
@ -28,5 +29,20 @@ func NewLangVersionDataLoaders(langTag models.LanguageTag, cfg Config) *LangVers
return inOrder, nil
},
},
PlayerNameChangesByID: PlayerNameChangesLoader{
wait: 2 * time.Millisecond,
maxBatch: 0,
fetch: func(keys []int) ([][]*models.PlayerNameChange, []error) {
playerNameChangesByID, err := cfg.PlayerRepo.FetchNameChanges(context.Background(), langTag, keys...)
if err != nil {
return nil, []error{err}
}
inOrder := make([][]*models.PlayerNameChange, len(keys))
for i, id := range keys {
inOrder[i] = playerNameChangesByID[id]
}
return inOrder, nil
},
},
}
}

View File

@ -0,0 +1,225 @@
// Code generated by github.com/vektah/dataloaden, DO NOT EDIT.
package dataloaders
import (
"sync"
"time"
"github.com/tribalwarshelp/shared/models"
)
// PlayerNameChangesLoaderConfig captures the config to create a new PlayerNameChangesLoader
type PlayerNameChangesLoaderConfig struct {
// Fetch is a method that provides the data for the loader
Fetch func(keys []int) ([][]*models.PlayerNameChange, []error)
// Wait is how long wait before sending a batch
Wait time.Duration
// MaxBatch will limit the maximum number of keys to send in one batch, 0 = not limit
MaxBatch int
}
// NewPlayerNameChangesLoader creates a new PlayerNameChangesLoader given a fetch, wait, and maxBatch
func NewPlayerNameChangesLoader(config PlayerNameChangesLoaderConfig) *PlayerNameChangesLoader {
return &PlayerNameChangesLoader{
fetch: config.Fetch,
wait: config.Wait,
maxBatch: config.MaxBatch,
}
}
// PlayerNameChangesLoader batches and caches requests
type PlayerNameChangesLoader struct {
// this method provides the data for the loader
fetch func(keys []int) ([][]*models.PlayerNameChange, []error)
// how long to done before sending a batch
wait time.Duration
// this will limit the maximum number of keys to send in one batch, 0 = no limit
maxBatch int
// INTERNAL
// lazily created cache
cache map[int][]*models.PlayerNameChange
// 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 *playerNameChangesLoaderBatch
// mutex to prevent races
mu sync.Mutex
}
type playerNameChangesLoaderBatch struct {
keys []int
data [][]*models.PlayerNameChange
error []error
closing bool
done chan struct{}
}
// Load a PlayerNameChange by key, batching and caching will be applied automatically
func (l *PlayerNameChangesLoader) Load(key int) ([]*models.PlayerNameChange, error) {
return l.LoadThunk(key)()
}
// 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
// different data loaders without blocking until the thunk is called.
func (l *PlayerNameChangesLoader) LoadThunk(key int) func() ([]*models.PlayerNameChange, error) {
l.mu.Lock()
if it, ok := l.cache[key]; ok {
l.mu.Unlock()
return func() ([]*models.PlayerNameChange, error) {
return it, nil
}
}
if l.batch == nil {
l.batch = &playerNameChangesLoaderBatch{done: make(chan struct{})}
}
batch := l.batch
pos := batch.keyIndex(l, key)
l.mu.Unlock()
return func() ([]*models.PlayerNameChange, error) {
<-batch.done
var data []*models.PlayerNameChange
if pos < len(batch.data) {
data = batch.data[pos]
}
var err error
// its convenient to be able to return a single error for everything
if len(batch.error) == 1 {
err = batch.error[0]
} else if batch.error != nil {
err = batch.error[pos]
}
if err == nil {
l.mu.Lock()
l.unsafeSet(key, data)
l.mu.Unlock()
}
return data, err
}
}
// LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured
func (l *PlayerNameChangesLoader) LoadAll(keys []int) ([][]*models.PlayerNameChange, []error) {
results := make([]func() ([]*models.PlayerNameChange, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
playerNameChanges := make([][]*models.PlayerNameChange, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
playerNameChanges[i], errors[i] = thunk()
}
return playerNameChanges, errors
}
// 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
// different data loaders without blocking until the thunk is called.
func (l *PlayerNameChangesLoader) LoadAllThunk(keys []int) func() ([][]*models.PlayerNameChange, []error) {
results := make([]func() ([]*models.PlayerNameChange, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
return func() ([][]*models.PlayerNameChange, []error) {
playerNameChanges := make([][]*models.PlayerNameChange, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
playerNameChanges[i], errors[i] = thunk()
}
return playerNameChanges, 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 *PlayerNameChangesLoader) Prime(key int, value []*models.PlayerNameChange) bool {
l.mu.Lock()
var found bool
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
// and end up with the whole cache pointing to the same value.
cpy := make([]*models.PlayerNameChange, len(value))
copy(cpy, value)
l.unsafeSet(key, cpy)
}
l.mu.Unlock()
return !found
}
// Clear the value at key from the cache, if it exists
func (l *PlayerNameChangesLoader) Clear(key int) {
l.mu.Lock()
delete(l.cache, key)
l.mu.Unlock()
}
func (l *PlayerNameChangesLoader) unsafeSet(key int, value []*models.PlayerNameChange) {
if l.cache == nil {
l.cache = map[int][]*models.PlayerNameChange{}
}
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 *playerNameChangesLoaderBatch) keyIndex(l *PlayerNameChangesLoader, key int) int {
for i, existingKey := range b.keys {
if key == existingKey {
return i
}
}
pos := len(b.keys)
b.keys = append(b.keys, key)
if pos == 0 {
go b.startTimer(l)
}
if l.maxBatch != 0 && pos >= l.maxBatch-1 {
if !b.closing {
b.closing = true
l.batch = nil
go b.end(l)
}
}
return pos
}
func (b *playerNameChangesLoaderBatch) startTimer(l *PlayerNameChangesLoader) {
time.Sleep(l.wait)
l.mu.Lock()
// we must have hit a batch limit and are already finalizing this batch
if b.closing {
l.mu.Unlock()
return
}
l.batch = nil
l.mu.Unlock()
b.end(l)
}
func (b *playerNameChangesLoaderBatch) end(l *PlayerNameChangesLoader) {
b.data, b.error = l.fetch(b.keys)
close(b.done)
}

View File

@ -121,10 +121,12 @@ type ComplexityRoot struct {
Player struct {
DailyGrowth func(childComplexity int) int
DeletedAt func(childComplexity int) int
Exist func(childComplexity int) int
ID func(childComplexity int) int
JoinedAt func(childComplexity int) int
Name func(childComplexity int) int
NameChanges func(childComplexity int) int
Points func(childComplexity int) int
Rank func(childComplexity int) int
RankAtt func(childComplexity int) int
@ -162,6 +164,12 @@ type ComplexityRoot struct {
Tribe func(childComplexity int) int
}
PlayerNameChange struct {
ChangedOn func(childComplexity int) int
NewName func(childComplexity int) int
OldName func(childComplexity int) int
}
PlayersList struct {
Items func(childComplexity int) int
Total func(childComplexity int) int
@ -378,6 +386,7 @@ type ComplexityRoot struct {
Tribe struct {
AllPoints func(childComplexity int) int
CreatedAt func(childComplexity int) int
DeletedAt func(childComplexity int) int
Dominance func(childComplexity int) int
Exist func(childComplexity int) int
ID func(childComplexity int) int
@ -492,6 +501,7 @@ type LiveEnnoblementResolver interface {
type PlayerResolver interface {
Tribe(ctx context.Context, obj *models.Player) (*models.Tribe, error)
Servers(ctx context.Context, obj *models.Player) ([]string, error)
NameChanges(ctx context.Context, obj *models.Player) ([]*models.PlayerNameChange, error)
}
type PlayerHistoryRecordResolver interface {
Player(ctx context.Context, obj *models.PlayerHistory) (*models.Player, error)
@ -882,6 +892,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Player.DailyGrowth(childComplexity), true
case "Player.deletedAt":
if e.complexity.Player.DeletedAt == nil {
break
}
return e.complexity.Player.DeletedAt(childComplexity), true
case "Player.exist":
if e.complexity.Player.Exist == nil {
break
@ -910,6 +927,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Player.Name(childComplexity), true
case "Player.nameChanges":
if e.complexity.Player.NameChanges == nil {
break
}
return e.complexity.Player.NameChanges(childComplexity), true
case "Player.points":
if e.complexity.Player.Points == nil {
break
@ -1113,6 +1137,27 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.PlayerHistoryRecord.Tribe(childComplexity), true
case "PlayerNameChange.changedOn":
if e.complexity.PlayerNameChange.ChangedOn == nil {
break
}
return e.complexity.PlayerNameChange.ChangedOn(childComplexity), true
case "PlayerNameChange.newName":
if e.complexity.PlayerNameChange.NewName == nil {
break
}
return e.complexity.PlayerNameChange.NewName(childComplexity), true
case "PlayerNameChange.oldName":
if e.complexity.PlayerNameChange.OldName == nil {
break
}
return e.complexity.PlayerNameChange.OldName(childComplexity), true
case "PlayersList.items":
if e.complexity.PlayersList.Items == nil {
break
@ -2278,6 +2323,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Tribe.CreatedAt(childComplexity), true
case "Tribe.deletedAt":
if e.complexity.Tribe.DeletedAt == nil {
break
}
return e.complexity.Tribe.DeletedAt(childComplexity), true
case "Tribe.dominance":
if e.complexity.Tribe.Dominance == nil {
break
@ -2942,7 +2994,13 @@ extend type Query {
liveEnnoblements(server: String!): [LiveEnnoblement!]
}
`, BuiltIn: false},
&ast.Source{Name: "schema/player.graphql", Input: `type Player {
&ast.Source{Name: "schema/player.graphql", Input: `type PlayerNameChange {
oldName: String!
newName: String!
changedOn: Time!
}
type Player {
id: Int!
name: String!
totalVillages: Int!
@ -2959,8 +3017,10 @@ extend type Query {
scoreTotal: Int!
dailyGrowth: Int!
joinedAt: Time!
deletedAt: Time
tribe: Tribe @goField(forceResolver: true)
servers: [String!]! @goField(forceResolver: true)
nameChanges: [PlayerNameChange!]! @goField(forceResolver: true)
}
type PlayersList {
@ -3057,6 +3117,12 @@ input PlayerFilter {
joinedAtLT: Time
joinedAtLTE: Time
deletedAt: Time
deletedAtGT: Time
deletedAtGTE: Time
deletedAtLT: Time
deletedAtLTE: Time
tribeID: [Int!]
tribeFilter: TribeFilter
@ -3363,9 +3429,10 @@ extend type Query {
rankDef: Int!
scoreDef: Int!
rankTotal: Int!
scoreTotal: Int!
dominance: Float!
createdAt: Time!
scoreTotal: Int!
deletedAt: Time!
}
type TribesList {
@ -3467,6 +3534,12 @@ input TribeFilter {
createdAtLT: Time
createdAtLTE: Time
deletedAt: Time
deletedAtGT: Time
deletedAtGTE: Time
deletedAtLT: Time
deletedAtLTE: Time
offset: Int
limit: Int
sort: String
@ -6121,6 +6194,37 @@ func (ec *executionContext) _Player_joinedAt(ctx context.Context, field graphql.
return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
}
func (ec *executionContext) _Player_deletedAt(ctx context.Context, field graphql.CollectedField, obj *models.Player) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Player",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.DeletedAt, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(time.Time)
fc.Result = res
return ec.marshalOTime2timeᚐTime(ctx, field.Selections, res)
}
func (ec *executionContext) _Player_tribe(ctx context.Context, field graphql.CollectedField, obj *models.Player) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -6186,6 +6290,40 @@ func (ec *executionContext) _Player_servers(ctx context.Context, field graphql.C
return ec.marshalNString2ᚕstringᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _Player_nameChanges(ctx context.Context, field graphql.CollectedField, obj *models.Player) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Player",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Player().NameChanges(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]*models.PlayerNameChange)
fc.Result = res
return ec.marshalNPlayerNameChange2ᚕᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐPlayerNameChangeᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _PlayerHistory_total(ctx context.Context, field graphql.CollectedField, obj *PlayerHistory) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -6721,6 +6859,108 @@ func (ec *executionContext) _PlayerHistoryRecord_createdAt(ctx context.Context,
return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
}
func (ec *executionContext) _PlayerNameChange_oldName(ctx context.Context, field graphql.CollectedField, obj *models.PlayerNameChange) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "PlayerNameChange",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.OldName, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _PlayerNameChange_newName(ctx context.Context, field graphql.CollectedField, obj *models.PlayerNameChange) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "PlayerNameChange",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.NewName, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _PlayerNameChange_changedOn(ctx context.Context, field graphql.CollectedField, obj *models.PlayerNameChange) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "PlayerNameChange",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.ChangedOn, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(time.Time)
fc.Result = res
return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
}
func (ec *executionContext) _PlayersList_items(ctx context.Context, field graphql.CollectedField, obj *PlayersList) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -12550,6 +12790,40 @@ func (ec *executionContext) _Tribe_rankTotal(ctx context.Context, field graphql.
return ec.marshalNInt2int(ctx, field.Selections, res)
}
func (ec *executionContext) _Tribe_scoreTotal(ctx context.Context, field graphql.CollectedField, obj *models.Tribe) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Tribe",
Field: field,
Args: nil,
IsMethod: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.ScoreTotal, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(int)
fc.Result = res
return ec.marshalNInt2int(ctx, field.Selections, res)
}
func (ec *executionContext) _Tribe_dominance(ctx context.Context, field graphql.CollectedField, obj *models.Tribe) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -12618,7 +12892,7 @@ func (ec *executionContext) _Tribe_createdAt(ctx context.Context, field graphql.
return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
}
func (ec *executionContext) _Tribe_scoreTotal(ctx context.Context, field graphql.CollectedField, obj *models.Tribe) (ret graphql.Marshaler) {
func (ec *executionContext) _Tribe_deletedAt(ctx context.Context, field graphql.CollectedField, obj *models.Tribe) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
@ -12635,7 +12909,7 @@ func (ec *executionContext) _Tribe_scoreTotal(ctx context.Context, field graphql
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.ScoreTotal, nil
return obj.DeletedAt, nil
})
if err != nil {
ec.Error(ctx, err)
@ -12647,9 +12921,9 @@ func (ec *executionContext) _Tribe_scoreTotal(ctx context.Context, field graphql
}
return graphql.Null
}
res := resTmp.(int)
res := resTmp.(time.Time)
fc.Result = res
return ec.marshalNInt2int(ctx, field.Selections, res)
return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
}
func (ec *executionContext) _TribeChangeRecord_player(ctx context.Context, field graphql.CollectedField, obj *models.TribeChange) (ret graphql.Marshaler) {
@ -16140,6 +16414,36 @@ func (ec *executionContext) unmarshalInputPlayerFilter(ctx context.Context, obj
if err != nil {
return it, err
}
case "deletedAt":
var err error
it.DeletedAt, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "deletedAtGT":
var err error
it.DeletedAtGT, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "deletedAtGTE":
var err error
it.DeletedAtGTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "deletedAtLT":
var err error
it.DeletedAtLT, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "deletedAtLTE":
var err error
it.DeletedAtLTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "tribeID":
var err error
it.TribeID, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v)
@ -16944,6 +17248,36 @@ func (ec *executionContext) unmarshalInputTribeFilter(ctx context.Context, obj i
if err != nil {
return it, err
}
case "deletedAt":
var err error
it.DeletedAt, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "deletedAtGT":
var err error
it.DeletedAtGT, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "deletedAtGTE":
var err error
it.DeletedAtGTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "deletedAtLT":
var err error
it.DeletedAtLT, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "deletedAtLTE":
var err error
it.DeletedAtLTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v)
if err != nil {
return it, err
}
case "offset":
var err error
it.Offset, err = ec.unmarshalOInt2int(ctx, v)
@ -17756,6 +18090,8 @@ func (ec *executionContext) _Player(ctx context.Context, sel ast.SelectionSet, o
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "deletedAt":
out.Values[i] = ec._Player_deletedAt(ctx, field, obj)
case "tribe":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
@ -17781,6 +18117,20 @@ func (ec *executionContext) _Player(ctx context.Context, sel ast.SelectionSet, o
}
return res
})
case "nameChanges":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Player_nameChanges(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@ -17925,6 +18275,43 @@ func (ec *executionContext) _PlayerHistoryRecord(ctx context.Context, sel ast.Se
return out
}
var playerNameChangeImplementors = []string{"PlayerNameChange"}
func (ec *executionContext) _PlayerNameChange(ctx context.Context, sel ast.SelectionSet, obj *models.PlayerNameChange) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, playerNameChangeImplementors)
out := graphql.NewFieldSet(fields)
var invalids uint32
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("PlayerNameChange")
case "oldName":
out.Values[i] = ec._PlayerNameChange_oldName(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "newName":
out.Values[i] = ec._PlayerNameChange_newName(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "changedOn":
out.Values[i] = ec._PlayerNameChange_changedOn(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch()
if invalids > 0 {
return graphql.Null
}
return out
}
var playersListImplementors = []string{"PlayersList"}
func (ec *executionContext) _PlayersList(ctx context.Context, sel ast.SelectionSet, obj *PlayersList) graphql.Marshaler {
@ -19342,6 +19729,11 @@ func (ec *executionContext) _Tribe(ctx context.Context, sel ast.SelectionSet, ob
if out.Values[i] == graphql.Null {
invalids++
}
case "scoreTotal":
out.Values[i] = ec._Tribe_scoreTotal(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "dominance":
out.Values[i] = ec._Tribe_dominance(ctx, field, obj)
if out.Values[i] == graphql.Null {
@ -19352,8 +19744,8 @@ func (ec *executionContext) _Tribe(ctx context.Context, sel ast.SelectionSet, ob
if out.Values[i] == graphql.Null {
invalids++
}
case "scoreTotal":
out.Values[i] = ec._Tribe_scoreTotal(ctx, field, obj)
case "deletedAt":
out.Values[i] = ec._Tribe_deletedAt(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
@ -20288,6 +20680,57 @@ func (ec *executionContext) marshalNPlayerHistoryRecord2ᚖgithubᚗcomᚋtribal
return ec._PlayerHistoryRecord(ctx, sel, v)
}
func (ec *executionContext) marshalNPlayerNameChange2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐPlayerNameChange(ctx context.Context, sel ast.SelectionSet, v models.PlayerNameChange) graphql.Marshaler {
return ec._PlayerNameChange(ctx, sel, &v)
}
func (ec *executionContext) marshalNPlayerNameChange2ᚕᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐPlayerNameChangeᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.PlayerNameChange) graphql.Marshaler {
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
isLen1 := len(v) == 1
if !isLen1 {
wg.Add(len(v))
}
for i := range v {
i := i
fc := &graphql.FieldContext{
Index: &i,
Result: &v[i],
}
ctx := graphql.WithFieldContext(ctx, fc)
f := func(i int) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = nil
}
}()
if !isLen1 {
defer wg.Done()
}
ret[i] = ec.marshalNPlayerNameChange2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐPlayerNameChange(ctx, sel, v[i])
}
if isLen1 {
f(i)
} else {
go f(i)
}
}
wg.Wait()
return ret
}
func (ec *executionContext) marshalNPlayerNameChange2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐPlayerNameChange(ctx context.Context, sel ast.SelectionSet, v *models.PlayerNameChange) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
return ec._PlayerNameChange(ctx, sel, v)
}
func (ec *executionContext) marshalNPlayersList2githubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐPlayersList(ctx context.Context, sel ast.SelectionSet, v PlayersList) graphql.Marshaler {
return ec._PlayersList(ctx, sel, &v)
}

View File

@ -94,3 +94,5 @@ models:
model: github.com/tribalwarshelp/shared/models.TribeChange
TribeChangeFilter:
model: github.com/tribalwarshelp/shared/models.TribeChangeFilter
PlayerNameChange:
model: github.com/tribalwarshelp/shared/models.PlayerNameChange

View File

@ -31,6 +31,20 @@ func (r *playerResolver) Servers(ctx context.Context, obj *models.Player) ([]str
return []string{}, nil
}
func (r *playerResolver) NameChanges(ctx context.Context, obj *models.Player) ([]*models.PlayerNameChange, error) {
langVersionDataLoaders := middleware.LangVersionDataLoadersFromContext(ctx)
if langVersionDataLoaders != nil {
serverKey, _ := getServer(ctx)
if loaders, ok := langVersionDataLoaders[utils.LanguageTagFromServerKey(serverKey)]; ok {
servers, err := loaders.PlayerNameChangesByID.Load(obj.ID)
if err == nil {
return servers, nil
}
}
}
return []*models.PlayerNameChange{}, nil
}
func (r *queryResolver) Players(ctx context.Context, server string, filter *models.PlayerFilter) (*generated.PlayersList, error) {
var err error
list := &generated.PlayersList{}

View File

@ -1,3 +1,9 @@
type PlayerNameChange {
oldName: String!
newName: String!
changedOn: Time!
}
type Player {
id: Int!
name: String!
@ -15,8 +21,10 @@ type Player {
scoreTotal: Int!
dailyGrowth: Int!
joinedAt: Time!
deletedAt: Time
tribe: Tribe @goField(forceResolver: true)
servers: [String!]! @goField(forceResolver: true)
nameChanges: [PlayerNameChange!]! @goField(forceResolver: true)
}
type PlayersList {
@ -113,6 +121,12 @@ input PlayerFilter {
joinedAtLT: Time
joinedAtLTE: Time
deletedAt: Time
deletedAtGT: Time
deletedAtGTE: Time
deletedAtLT: Time
deletedAtLTE: Time
tribeID: [Int!]
tribeFilter: TribeFilter

View File

@ -13,9 +13,10 @@ type Tribe {
rankDef: Int!
scoreDef: Int!
rankTotal: Int!
scoreTotal: Int!
dominance: Float!
createdAt: Time!
scoreTotal: Int!
deletedAt: Time!
}
type TribesList {
@ -117,6 +118,12 @@ input TribeFilter {
createdAtLT: Time
createdAtLTE: Time
deletedAt: Time
deletedAtGT: Time
deletedAtGTE: Time
deletedAtLT: Time
deletedAtLTE: Time
offset: Int
limit: Int
sort: String

View File

@ -14,5 +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)
}

View File

@ -64,6 +64,23 @@ type fetchPlayerServersQueryResult struct {
Servers []string `pg:",array"`
}
func (repo *pgRepository) FetchNameChanges(ctx context.Context, langTag models.LanguageTag, playerID ...int) (map[int][]*models.PlayerNameChange, error) {
data := []*models.PlayerNameChange{}
if err := repo.Model(&data).
Context(ctx).
Where("lang_version_tag = ?", langTag).
Where("player_id IN (?)", pg.In(playerID)).
Select(); err != nil && err != pg.ErrNoRows {
return nil, errors.Wrap(err, "Internal server error")
}
m := make(map[int][]*models.PlayerNameChange)
for _, res := range data {
m[res.PlayerID] = append(m[res.PlayerID], res)
}
return m, nil
}
func (repo *pgRepository) FetchPlayerServers(ctx context.Context, langTag models.LanguageTag, playerID ...int) (map[int][]string, error) {
data := []*fetchPlayerServersQueryResult{}
if err := repo.Model(&models.PlayerToServer{}).