From 87562c3f4c111bb905fd3b221c96259518fd50c1 Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Wed, 24 Jun 2020 15:05:31 +0200 Subject: [PATCH 1/5] every date which API returns are in UTC timezone, resolver Player.Servers() is returning now servers from one specific game lang version, refactor --- ennoblement/repository.go | 10 +- ennoblement/repository/pg_repository.go | 25 +- ennoblement/usecase/ennoblement_usecase.go | 6 +- go.sum | 2 - graphql/dataloaders/data_loaders.go | 26 +- .../dataloaders/lang_version_data_loaders.go | 32 ++ graphql/dataloaders/server_data_loaders.go | 16 +- graphql/generated/generated.go | 330 ++++++------------ graphql/resolvers/ennoblement.go | 9 - graphql/resolvers/helpers.go | 13 - graphql/resolvers/player.go | 20 +- graphql/resolvers/player_history.go | 8 - graphql/resolvers/resolver.go | 4 - graphql/resolvers/server.go | 16 - graphql/resolvers/server_stats.go | 8 - graphql/resolvers/tribe.go | 8 - graphql/resolvers/tribe_history.go | 8 - graphql/schema/ennoblements.graphql | 2 +- graphql/schema/player.graphql | 2 +- graphql/schema/player_history.graphql | 2 +- graphql/schema/server.graphql | 6 +- graphql/schema/server_stats.graphql | 2 +- graphql/schema/tribe.graphql | 2 +- graphql/schema/tribe_history.graphql | 2 +- langversion/repository.go | 9 +- langversion/repository/pg_repository.go | 21 +- langversion/usecase/langversion_usecase.go | 15 +- liveennoblement/repository/line_parser.go | 11 +- liveennoblement/repository/pg_repository.go | 5 +- main.go | 4 +- middleware/dataloaders_to_context.go | 30 +- player/repository.go | 12 +- player/repository/pg_repository.go | 37 +- player/usecase/player_usecase.go | 17 +- playerhistory/repository.go | 10 +- playerhistory/repository/pg_repository.go | 25 +- .../usecase/playerhistory_usecase.go | 6 +- server/repository.go | 9 +- server/repository/pg_repository.go | 21 +- server/usecase/server_usecase.go | 15 +- serverstats/repository.go | 10 +- serverstats/repository/pg_repository.go | 25 +- serverstats/usecase/serverstats_usecase.go | 6 +- tribe/repository.go | 10 +- tribe/repository/pg_repository.go | 29 +- tribe/usecase/tribe_usecase.go | 17 +- tribehistory/repository.go | 10 +- tribehistory/repository/pg_repository.go | 25 +- tribehistory/usecase/tribehistory_usecase.go | 6 +- utils/get_location.go | 4 +- 50 files changed, 460 insertions(+), 488 deletions(-) create mode 100644 graphql/dataloaders/lang_version_data_loaders.go diff --git a/ennoblement/repository.go b/ennoblement/repository.go index 5ee3cb4..1a18044 100644 --- a/ennoblement/repository.go +++ b/ennoblement/repository.go @@ -6,6 +6,12 @@ import ( "github.com/tribalwarshelp/shared/models" ) -type Repository interface { - Fetch(ctx context.Context, server string, filter *models.EnnoblementFilter) ([]*models.Ennoblement, int, error) +type FetchConfig struct { + Server string + Filter *models.EnnoblementFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Ennoblement, int, error) } diff --git a/ennoblement/repository/pg_repository.go b/ennoblement/repository/pg_repository.go index 17791cb..590b1f0 100644 --- a/ennoblement/repository/pg_repository.go +++ b/ennoblement/repository/pg_repository.go @@ -19,25 +19,30 @@ func NewPGRepository(db *pg.DB) ennoblement.Repository { return &pgRepository{db} } -func (repo *pgRepository) Fetch(ctx context.Context, server string, f *models.EnnoblementFilter) ([]*models.Ennoblement, int, error) { +func (repo *pgRepository) Fetch(ctx context.Context, cfg ennoblement.FetchConfig) ([]*models.Ennoblement, int, error) { var err error + total := 0 data := []*models.Ennoblement{} - query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx) + query := repo.WithParam("SERVER", pg.Safe(cfg.Server)).Model(&data).Context(ctx) - if f != nil { + if cfg.Filter != nil { query = query. - WhereStruct(f). - Limit(f.Limit). - Offset(f.Offset) + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) - if f.Sort != "" { - query = query.Order(f.Sort) + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) } } - total, err := query.SelectAndCount() + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } if err != nil && err != pg.ErrNoRows { - if strings.Contains(err.Error(), `relation "`+server) { + if strings.Contains(err.Error(), `relation "`+cfg.Server) { return nil, 0, fmt.Errorf("Server not found") } return nil, 0, errors.Wrap(err, "Internal server error") diff --git a/ennoblement/usecase/ennoblement_usecase.go b/ennoblement/usecase/ennoblement_usecase.go index 286a87e..3b02419 100644 --- a/ennoblement/usecase/ennoblement_usecase.go +++ b/ennoblement/usecase/ennoblement_usecase.go @@ -24,5 +24,9 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.E filter.Limit = ennoblement.PaginationLimit } filter.Sort = utils.SanitizeSort(filter.Sort) - return ucase.repo.Fetch(ctx, server, filter) + return ucase.repo.Fetch(ctx, ennoblement.FetchConfig{ + Server: server, + Filter: filter, + Count: true, + }) } diff --git a/go.sum b/go.sum index 5d7704e..d87d8b5 100644 --- a/go.sum +++ b/go.sum @@ -175,8 +175,6 @@ github.com/tribalwarshelp/map-generator v0.0.0-20200623143352-cc037d744be2 h1:jk github.com/tribalwarshelp/map-generator v0.0.0-20200623143352-cc037d744be2/go.mod h1:h3INS/arc4MelQjePKvXdrqWjHVVm2s4PKSrsMmkZx8= github.com/tribalwarshelp/shared v0.0.0-20200622084436-3a768c8bf574 h1:y2EoH6zRK9Uc0AeswnJRYUUIQYcSLZB5VDFuxPCKxNM= github.com/tribalwarshelp/shared v0.0.0-20200622084436-3a768c8bf574/go.mod h1:tf+2yTHasV6jAF3V2deZ9slNoCyBzC0fMdTjI7clf6Y= -github.com/tribalwarshelp/shared v0.0.0-20200623082627-128bf01a6570 h1:W2cBKRRvr1QLG2GzuJFuvtVe0dblHkkb+E2SlbdJBHo= -github.com/tribalwarshelp/shared v0.0.0-20200623082627-128bf01a6570/go.mod h1:tf+2yTHasV6jAF3V2deZ9slNoCyBzC0fMdTjI7clf6Y= github.com/tribalwarshelp/shared v0.0.0-20200623144748-aa834a01dce6 h1:WZ1oxHysFtiPjHa2ADUqiGrzwcN3j0YpiVg/V2e/74o= github.com/tribalwarshelp/shared v0.0.0-20200623144748-aa834a01dce6/go.mod h1:tf+2yTHasV6jAF3V2deZ9slNoCyBzC0fMdTjI7clf6Y= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= diff --git a/graphql/dataloaders/data_loaders.go b/graphql/dataloaders/data_loaders.go index cd3374a..1dcb82d 100644 --- a/graphql/dataloaders/data_loaders.go +++ b/graphql/dataloaders/data_loaders.go @@ -12,8 +12,7 @@ import ( ) type DataLoaders struct { - LangVersionByTag LangVersionLoader - PlayerServersByID PlayerServersLoader + LangVersionByTag LangVersionLoader } type Config struct { @@ -23,7 +22,7 @@ type Config struct { LangVersionRepo langversion.Repository } -func New(cfg Config) *DataLoaders { +func NewDataLoaders(cfg Config) *DataLoaders { return &DataLoaders{ LangVersionByTag: LangVersionLoader{ wait: 2 * time.Millisecond, @@ -33,8 +32,10 @@ func New(cfg Config) *DataLoaders { for _, tag := range keys { tags = append(tags, models.LanguageTag(tag)) } - langVersions, _, err := cfg.LangVersionRepo.Fetch(context.Background(), &models.LangVersionFilter{ - Tag: tags, + langVersions, _, err := cfg.LangVersionRepo.Fetch(context.Background(), langversion.FetchConfig{ + Filter: &models.LangVersionFilter{ + Tag: tags, + }, }) if err != nil { return nil, []error{err} @@ -53,20 +54,5 @@ func New(cfg Config) *DataLoaders { return inOrder, nil }, }, - PlayerServersByID: PlayerServersLoader{ - wait: 2 * time.Millisecond, - maxBatch: 0, - fetch: func(keys []int) ([][]string, []error) { - playerServersByID, err := cfg.PlayerRepo.FetchPlayerServers(context.Background(), keys...) - if err != nil { - return nil, []error{err} - } - inOrder := make([][]string, len(keys)) - for i, id := range keys { - inOrder[i] = playerServersByID[id] - } - return inOrder, nil - }, - }, } } diff --git a/graphql/dataloaders/lang_version_data_loaders.go b/graphql/dataloaders/lang_version_data_loaders.go new file mode 100644 index 0000000..6550e80 --- /dev/null +++ b/graphql/dataloaders/lang_version_data_loaders.go @@ -0,0 +1,32 @@ +package dataloaders + +import ( + "context" + "time" + + "github.com/tribalwarshelp/shared/models" +) + +type LangVersionDataLoaders struct { + PlayerServersByID PlayerServersLoader +} + +func NewLangVersionDataLoaders(langTag models.LanguageTag, cfg Config) *LangVersionDataLoaders { + return &LangVersionDataLoaders{ + PlayerServersByID: PlayerServersLoader{ + wait: 2 * time.Millisecond, + maxBatch: 0, + fetch: func(keys []int) ([][]string, []error) { + playerServersByID, err := cfg.PlayerRepo.FetchPlayerServers(context.Background(), langTag, keys...) + if err != nil { + return nil, []error{err} + } + inOrder := make([][]string, len(keys)) + for i, id := range keys { + inOrder[i] = playerServersByID[id] + } + return inOrder, nil + }, + }, + } +} diff --git a/graphql/dataloaders/server_data_loaders.go b/graphql/dataloaders/server_data_loaders.go index 75024ff..dc55050 100644 --- a/graphql/dataloaders/server_data_loaders.go +++ b/graphql/dataloaders/server_data_loaders.go @@ -4,6 +4,8 @@ import ( "context" "time" + "github.com/tribalwarshelp/api/player" + "github.com/tribalwarshelp/api/tribe" "github.com/tribalwarshelp/api/village" "github.com/tribalwarshelp/shared/models" ) @@ -20,8 +22,11 @@ func NewServerDataLoaders(server string, cfg Config) *ServerDataLoaders { wait: 2 * time.Millisecond, maxBatch: 0, fetch: func(ids []int) ([]*models.Player, []error) { - players, _, err := cfg.PlayerRepo.Fetch(context.Background(), server, &models.PlayerFilter{ - ID: ids, + players, _, err := cfg.PlayerRepo.Fetch(context.Background(), player.FetchConfig{ + Filter: &models.PlayerFilter{ + ID: ids, + }, + Server: server, }) if err != nil { return nil, []error{err} @@ -44,8 +49,11 @@ func NewServerDataLoaders(server string, cfg Config) *ServerDataLoaders { wait: 2 * time.Millisecond, maxBatch: 0, fetch: func(ids []int) ([]*models.Tribe, []error) { - tribes, _, err := cfg.TribeRepo.Fetch(context.Background(), server, &models.TribeFilter{ - ID: ids, + tribes, _, err := cfg.TribeRepo.Fetch(context.Background(), tribe.FetchConfig{ + Server: server, + Filter: &models.TribeFilter{ + ID: ids, + }, }) if err != nil { return nil, []error{err} diff --git a/graphql/generated/generated.go b/graphql/generated/generated.go index 35eca17..e35a069 100644 --- a/graphql/generated/generated.go +++ b/graphql/generated/generated.go @@ -42,8 +42,6 @@ type ResolverRoot interface { PlayerHistoryRecord() PlayerHistoryRecordResolver Query() QueryResolver Server() ServerResolver - ServerStatsRecord() ServerStatsRecordResolver - Tribe() TribeResolver TribeHistoryRecord() TribeHistoryRecordResolver Village() VillageResolver } @@ -471,7 +469,6 @@ type EnnoblementResolver interface { NewOwnerTribe(ctx context.Context, obj *models.Ennoblement) (*models.Tribe, error) OldOwner(ctx context.Context, obj *models.Ennoblement) (*models.Player, error) OldOwnerTribe(ctx context.Context, obj *models.Ennoblement) (*models.Tribe, error) - EnnobledAt(ctx context.Context, obj *models.Ennoblement) (*time.Time, error) } type LiveEnnoblementResolver interface { Village(ctx context.Context, obj *models.LiveEnnoblement) (*models.Village, error) @@ -479,7 +476,6 @@ type LiveEnnoblementResolver interface { OldOwner(ctx context.Context, obj *models.LiveEnnoblement) (*models.Player, error) } type PlayerResolver interface { - JoinedAt(ctx context.Context, obj *models.Player) (*time.Time, error) Tribe(ctx context.Context, obj *models.Player) (*models.Tribe, error) Servers(ctx context.Context, obj *models.Player) ([]string, error) } @@ -487,7 +483,6 @@ type PlayerHistoryRecordResolver interface { Player(ctx context.Context, obj *models.PlayerHistory) (*models.Player, error) Tribe(ctx context.Context, obj *models.PlayerHistory) (*models.Tribe, error) - CreatedAt(ctx context.Context, obj *models.PlayerHistory) (*time.Time, error) } type QueryResolver interface { Ennoblements(ctx context.Context, server string, filter *models.EnnoblementFilter) (*EnnoblementsList, error) @@ -508,21 +503,9 @@ type QueryResolver interface { } type ServerResolver interface { LangVersion(ctx context.Context, obj *models.Server) (*models.LangVersion, error) - - DataUpdatedAt(ctx context.Context, obj *models.Server) (*time.Time, error) - HistoryUpdatedAt(ctx context.Context, obj *models.Server) (*time.Time, error) - StatsUpdatedAt(ctx context.Context, obj *models.Server) (*time.Time, error) -} -type ServerStatsRecordResolver interface { - CreatedAt(ctx context.Context, obj *models.ServerStats) (*time.Time, error) -} -type TribeResolver interface { - CreatedAt(ctx context.Context, obj *models.Tribe) (*time.Time, error) } type TribeHistoryRecordResolver interface { Tribe(ctx context.Context, obj *models.TribeHistory) (*models.Tribe, error) - - CreatedAt(ctx context.Context, obj *models.TribeHistory) (*time.Time, error) } type VillageResolver interface { Player(ctx context.Context, obj *models.Village) (*models.Player, error) @@ -2800,7 +2783,7 @@ type BuildingConfig { newOwnerTribe: Tribe @goField(forceResolver: true) oldOwner: Player @goField(forceResolver: true) oldOwnerTribe: Tribe @goField(forceResolver: true) - ennobledAt: Time! @goField(forceResolver: true) + ennobledAt: Time! } type EnnoblementsList { @@ -2901,7 +2884,7 @@ extend type Query { rankTotal: Int! scoreTotal: Int! dailyGrowth: Int! - joinedAt: Time! @goField(forceResolver: true) + joinedAt: Time! tribe: Tribe @goField(forceResolver: true) servers: [String!]! @goField(forceResolver: true) } @@ -3027,7 +3010,7 @@ extend type Query { rankTotal: Int! scoreTotal: Int! tribe: Tribe @goField(forceResolver: true) - createdAt: Time! @goField(forceResolver: true) + createdAt: Time! } type PlayerHistory { @@ -3074,9 +3057,9 @@ type Server { unitConfig: UnitConfig! buildingConfig: BuildingConfig! - dataUpdatedAt: Time! @goField(forceResolver: true) - historyUpdatedAt: Time! @goField(forceResolver: true) - statsUpdatedAt: Time! @goField(forceResolver: true) + dataUpdatedAt: Time! + historyUpdatedAt: Time! + statsUpdatedAt: Time! } type ServersList { @@ -3267,7 +3250,7 @@ type ServerConfig { barbarianVillages: Int! playerVillages: Int! villages: Int! - createdAt: Time! @goField(forceResolver: true) + createdAt: Time! } type ServerStats { @@ -3307,7 +3290,7 @@ extend type Query { scoreDef: Int! rankTotal: Int! dominance: Float! - createdAt: Time! @goField(forceResolver: true) + createdAt: Time! scoreTotal: Int! } @@ -3434,7 +3417,7 @@ extend type Query { scoreDef: Int! rankTotal: Int! scoreTotal: Int! - createdAt: Time! @goField(forceResolver: true) + createdAt: Time! } type TribeHistory { @@ -5045,13 +5028,13 @@ func (ec *executionContext) _Ennoblement_ennobledAt(ctx context.Context, field g Object: "Ennoblement", Field: field, Args: nil, - IsMethod: true, + 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 ec.resolvers.Ennoblement().EnnobledAt(rctx, obj) + return obj.EnnobledAt, nil }) if err != nil { ec.Error(ctx, err) @@ -5063,9 +5046,9 @@ func (ec *executionContext) _Ennoblement_ennobledAt(ctx context.Context, field g } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalNTime2ᚖtimeᚐTime(ctx, field.Selections, res) + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) _EnnoblementsList_items(ctx context.Context, field graphql.CollectedField, obj *EnnoblementsList) (ret graphql.Marshaler) { @@ -5982,13 +5965,13 @@ func (ec *executionContext) _Player_joinedAt(ctx context.Context, field graphql. Object: "Player", Field: field, Args: nil, - IsMethod: true, + 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 ec.resolvers.Player().JoinedAt(rctx, obj) + return obj.JoinedAt, nil }) if err != nil { ec.Error(ctx, err) @@ -6000,9 +5983,9 @@ func (ec *executionContext) _Player_joinedAt(ctx context.Context, field graphql. } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalNTime2ᚖtimeᚐTime(ctx, field.Selections, res) + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) _Player_tribe(ctx context.Context, field graphql.CollectedField, obj *models.Player) (ret graphql.Marshaler) { @@ -6582,13 +6565,13 @@ func (ec *executionContext) _PlayerHistoryRecord_createdAt(ctx context.Context, Object: "PlayerHistoryRecord", Field: field, Args: nil, - IsMethod: true, + 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 ec.resolvers.PlayerHistoryRecord().CreatedAt(rctx, obj) + return obj.CreatedAt, nil }) if err != nil { ec.Error(ctx, err) @@ -6600,9 +6583,9 @@ func (ec *executionContext) _PlayerHistoryRecord_createdAt(ctx context.Context, } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalNTime2ᚖtimeᚐTime(ctx, field.Selections, 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) { @@ -7650,13 +7633,13 @@ func (ec *executionContext) _Server_dataUpdatedAt(ctx context.Context, field gra Object: "Server", Field: field, Args: nil, - IsMethod: true, + 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 ec.resolvers.Server().DataUpdatedAt(rctx, obj) + return obj.DataUpdatedAt, nil }) if err != nil { ec.Error(ctx, err) @@ -7668,9 +7651,9 @@ func (ec *executionContext) _Server_dataUpdatedAt(ctx context.Context, field gra } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalNTime2ᚖtimeᚐTime(ctx, field.Selections, res) + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) _Server_historyUpdatedAt(ctx context.Context, field graphql.CollectedField, obj *models.Server) (ret graphql.Marshaler) { @@ -7684,13 +7667,13 @@ func (ec *executionContext) _Server_historyUpdatedAt(ctx context.Context, field Object: "Server", Field: field, Args: nil, - IsMethod: true, + 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 ec.resolvers.Server().HistoryUpdatedAt(rctx, obj) + return obj.HistoryUpdatedAt, nil }) if err != nil { ec.Error(ctx, err) @@ -7702,9 +7685,9 @@ func (ec *executionContext) _Server_historyUpdatedAt(ctx context.Context, field } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalNTime2ᚖtimeᚐTime(ctx, field.Selections, res) + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) _Server_statsUpdatedAt(ctx context.Context, field graphql.CollectedField, obj *models.Server) (ret graphql.Marshaler) { @@ -7718,13 +7701,13 @@ func (ec *executionContext) _Server_statsUpdatedAt(ctx context.Context, field gr Object: "Server", Field: field, Args: nil, - IsMethod: true, + 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 ec.resolvers.Server().StatsUpdatedAt(rctx, obj) + return obj.StatsUpdatedAt, nil }) if err != nil { ec.Error(ctx, err) @@ -7736,9 +7719,9 @@ func (ec *executionContext) _Server_statsUpdatedAt(ctx context.Context, field gr } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalNTime2ᚖtimeᚐTime(ctx, field.Selections, res) + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) _ServerConfig_speed(ctx context.Context, field graphql.CollectedField, obj *models.ServerConfig) (ret graphql.Marshaler) { @@ -11829,13 +11812,13 @@ func (ec *executionContext) _ServerStatsRecord_createdAt(ctx context.Context, fi Object: "ServerStatsRecord", Field: field, Args: nil, - IsMethod: true, + 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 ec.resolvers.ServerStatsRecord().CreatedAt(rctx, obj) + return obj.CreatedAt, nil }) if err != nil { ec.Error(ctx, err) @@ -11847,9 +11830,9 @@ func (ec *executionContext) _ServerStatsRecord_createdAt(ctx context.Context, fi } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalNTime2ᚖtimeᚐTime(ctx, field.Selections, res) + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) _ServersList_items(ctx context.Context, field graphql.CollectedField, obj *ServersList) (ret graphql.Marshaler) { @@ -12438,13 +12421,13 @@ func (ec *executionContext) _Tribe_createdAt(ctx context.Context, field graphql. Object: "Tribe", Field: field, Args: nil, - IsMethod: true, + 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 ec.resolvers.Tribe().CreatedAt(rctx, obj) + return obj.CreatedAt, nil }) if err != nil { ec.Error(ctx, err) @@ -12456,9 +12439,9 @@ func (ec *executionContext) _Tribe_createdAt(ctx context.Context, field graphql. } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalNTime2ᚖtimeᚐTime(ctx, field.Selections, res) + 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) { @@ -13010,13 +12993,13 @@ func (ec *executionContext) _TribeHistoryRecord_createdAt(ctx context.Context, f Object: "TribeHistoryRecord", Field: field, Args: nil, - IsMethod: true, + 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 ec.resolvers.TribeHistoryRecord().CreatedAt(rctx, obj) + return obj.CreatedAt, nil }) if err != nil { ec.Error(ctx, err) @@ -13028,9 +13011,9 @@ func (ec *executionContext) _TribeHistoryRecord_createdAt(ctx context.Context, f } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalNTime2ᚖtimeᚐTime(ctx, field.Selections, res) + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) _TribesList_items(ctx context.Context, field graphql.CollectedField, obj *TribesList) (ret graphql.Marshaler) { @@ -17045,19 +17028,10 @@ func (ec *executionContext) _Ennoblement(ctx context.Context, sel ast.SelectionS return res }) case "ennobledAt": - 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._Ennoblement_ennobledAt(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&invalids, 1) - } - return res - }) + out.Values[i] = ec._Ennoblement_ennobledAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -17316,19 +17290,10 @@ func (ec *executionContext) _Player(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } case "joinedAt": - 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_joinedAt(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&invalids, 1) - } - return res - }) + out.Values[i] = ec._Player_joinedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } case "tribe": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -17483,19 +17448,10 @@ func (ec *executionContext) _PlayerHistoryRecord(ctx context.Context, sel ast.Se return res }) case "createdAt": - 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._PlayerHistoryRecord_createdAt(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&invalids, 1) - } - return res - }) + out.Values[i] = ec._PlayerHistoryRecord_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -17821,47 +17777,20 @@ func (ec *executionContext) _Server(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } case "dataUpdatedAt": - 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._Server_dataUpdatedAt(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&invalids, 1) - } - return res - }) + out.Values[i] = ec._Server_dataUpdatedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } case "historyUpdatedAt": - 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._Server_historyUpdatedAt(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&invalids, 1) - } - return res - }) + out.Values[i] = ec._Server_historyUpdatedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } case "statsUpdatedAt": - 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._Server_statsUpdatedAt(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&invalids, 1) - } - return res - }) + out.Values[i] = ec._Server_statsUpdatedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -18764,67 +18693,58 @@ func (ec *executionContext) _ServerStatsRecord(ctx context.Context, sel ast.Sele case "activePlayers": out.Values[i] = ec._ServerStatsRecord_activePlayers(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "inactivePlayers": out.Values[i] = ec._ServerStatsRecord_inactivePlayers(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "players": out.Values[i] = ec._ServerStatsRecord_players(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "activeTribes": out.Values[i] = ec._ServerStatsRecord_activeTribes(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "inactiveTribes": out.Values[i] = ec._ServerStatsRecord_inactiveTribes(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "tribes": out.Values[i] = ec._ServerStatsRecord_tribes(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "bonusVillages": out.Values[i] = ec._ServerStatsRecord_bonusVillages(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "barbarianVillages": out.Values[i] = ec._ServerStatsRecord_barbarianVillages(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "playerVillages": out.Values[i] = ec._ServerStatsRecord_playerVillages(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "villages": out.Values[i] = ec._ServerStatsRecord_villages(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "createdAt": - 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._ServerStatsRecord_createdAt(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&invalids, 1) - } - return res - }) + out.Values[i] = ec._ServerStatsRecord_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -18879,96 +18799,87 @@ func (ec *executionContext) _Tribe(ctx context.Context, sel ast.SelectionSet, ob case "id": out.Values[i] = ec._Tribe_id(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "name": out.Values[i] = ec._Tribe_name(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "tag": out.Values[i] = ec._Tribe_tag(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "totalMembers": out.Values[i] = ec._Tribe_totalMembers(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "totalVillages": out.Values[i] = ec._Tribe_totalVillages(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "points": out.Values[i] = ec._Tribe_points(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "allPoints": out.Values[i] = ec._Tribe_allPoints(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "rank": out.Values[i] = ec._Tribe_rank(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "exist": out.Values[i] = ec._Tribe_exist(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "rankAtt": out.Values[i] = ec._Tribe_rankAtt(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "scoreAtt": out.Values[i] = ec._Tribe_scoreAtt(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "rankDef": out.Values[i] = ec._Tribe_rankDef(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "scoreDef": out.Values[i] = ec._Tribe_scoreDef(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "rankTotal": out.Values[i] = ec._Tribe_rankTotal(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "dominance": out.Values[i] = ec._Tribe_dominance(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } case "createdAt": - 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._Tribe_createdAt(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&invalids, 1) - } - return res - }) + out.Values[i] = ec._Tribe_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } case "scoreTotal": out.Values[i] = ec._Tribe_scoreTotal(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ } default: panic("unknown field " + strconv.Quote(field.Name)) @@ -19093,19 +19004,10 @@ func (ec *executionContext) _TribeHistoryRecord(ctx context.Context, sel ast.Sel atomic.AddUint32(&invalids, 1) } case "createdAt": - 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._TribeHistoryRecord_createdAt(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&invalids, 1) - } - return res - }) + out.Values[i] = ec._TribeHistoryRecord_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -20013,24 +19915,6 @@ func (ec *executionContext) marshalNTime2timeᚐTime(ctx context.Context, sel as return res } -func (ec *executionContext) unmarshalNTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) { - if v == nil { - return nil, nil - } - res, err := ec.unmarshalNTime2timeᚐTime(ctx, v) - return &res, err -} - -func (ec *executionContext) marshalNTime2ᚖtimeᚐTime(ctx context.Context, sel ast.SelectionSet, v *time.Time) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - return ec.marshalNTime2timeᚐTime(ctx, sel, *v) -} - func (ec *executionContext) marshalNTribe2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribe(ctx context.Context, sel ast.SelectionSet, v models.Tribe) graphql.Marshaler { return ec._Tribe(ctx, sel, &v) } diff --git a/graphql/resolvers/ennoblement.go b/graphql/resolvers/ennoblement.go index ba27c12..a52ec60 100644 --- a/graphql/resolvers/ennoblement.go +++ b/graphql/resolvers/ennoblement.go @@ -2,9 +2,6 @@ package resolvers import ( "context" - "time" - - "github.com/tribalwarshelp/api/utils" "github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/shared/models" @@ -50,12 +47,6 @@ func (r *ennoblementResolver) Village(ctx context.Context, obj *models.Ennobleme return getVillage(ctx, obj.VillageID), nil } -func (r *ennoblementResolver) EnnobledAt(ctx context.Context, obj *models.Ennoblement) (*time.Time, error) { - server, _ := getServer(ctx) - t := formatDate(ctx, utils.LanguageTagFromServerKey(server), obj.EnnobledAt) - return &t, nil -} - func (r *queryResolver) Ennoblements(ctx context.Context, server string, f *models.EnnoblementFilter) (*generated.EnnoblementsList, error) { var err error list := &generated.EnnoblementsList{} diff --git a/graphql/resolvers/helpers.go b/graphql/resolvers/helpers.go index 92e377b..f5f7724 100644 --- a/graphql/resolvers/helpers.go +++ b/graphql/resolvers/helpers.go @@ -2,11 +2,9 @@ package resolvers import ( "context" - "time" "github.com/99designs/gqlgen/graphql" "github.com/tribalwarshelp/api/middleware" - "github.com/tribalwarshelp/api/utils" "github.com/tribalwarshelp/shared/models" ) @@ -68,14 +66,3 @@ func getTribe(ctx context.Context, id int) *models.Tribe { } return nil } - -func formatDate(ctx context.Context, langTag models.LanguageTag, t time.Time) time.Time { - loaders := middleware.DataLoadersFromContext(ctx) - if loaders != nil { - lv, err := loaders.LangVersionByTag.Load(langTag.String()) - if err == nil { - return t.In(utils.GetLocation(lv.Timezone)) - } - } - return t -} diff --git a/graphql/resolvers/player.go b/graphql/resolvers/player.go index 0096b99..6b2bbe7 100644 --- a/graphql/resolvers/player.go +++ b/graphql/resolvers/player.go @@ -2,7 +2,6 @@ package resolvers import ( "context" - "time" "github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/middleware" @@ -19,22 +18,19 @@ func (r *playerResolver) Tribe(ctx context.Context, obj *models.Player) (*models } func (r *playerResolver) Servers(ctx context.Context, obj *models.Player) ([]string, error) { - loaders := middleware.DataLoadersFromContext(ctx) - if loaders != nil { - servers, err := loaders.PlayerServersByID.Load(obj.ID) - if err == nil { - return servers, nil + langVersionDataLoaders := middleware.LangVersionDataLoadersFromContext(ctx) + if langVersionDataLoaders != nil { + serverKey, _ := getServer(ctx) + if loaders, ok := langVersionDataLoaders[utils.LanguageTagFromServerKey(serverKey)]; ok { + servers, err := loaders.PlayerServersByID.Load(obj.ID) + if err == nil { + return servers, nil + } } } return []string{}, nil } -func (r *playerResolver) JoinedAt(ctx context.Context, obj *models.Player) (*time.Time, error) { - server, _ := getServer(ctx) - t := formatDate(ctx, utils.LanguageTagFromServerKey(server), obj.JoinedAt) - return &t, nil -} - func (r *queryResolver) Players(ctx context.Context, server string, filter *models.PlayerFilter) (*generated.PlayersList, error) { var err error list := &generated.PlayersList{} diff --git a/graphql/resolvers/player_history.go b/graphql/resolvers/player_history.go index 578ae99..46d21fd 100644 --- a/graphql/resolvers/player_history.go +++ b/graphql/resolvers/player_history.go @@ -2,10 +2,8 @@ package resolvers import ( "context" - "time" "github.com/tribalwarshelp/api/graphql/generated" - "github.com/tribalwarshelp/api/utils" "github.com/tribalwarshelp/shared/models" ) @@ -25,12 +23,6 @@ func (r *playerHistoryRecordResolver) Tribe(ctx context.Context, obj *models.Pla return getTribe(ctx, obj.TribeID), nil } -func (r *playerHistoryRecordResolver) CreatedAt(ctx context.Context, obj *models.PlayerHistory) (*time.Time, error) { - server, _ := getServer(ctx) - t := formatDate(ctx, utils.LanguageTagFromServerKey(server), obj.CreatedAt) - return &t, nil -} - func (r *Resolver) PlayerHistory(ctx context.Context, server string, filter *models.PlayerHistoryFilter) (*generated.PlayerHistory, error) { var err error list := &generated.PlayerHistory{} diff --git a/graphql/resolvers/resolver.go b/graphql/resolvers/resolver.go index c6a4f18..41946fe 100644 --- a/graphql/resolvers/resolver.go +++ b/graphql/resolvers/resolver.go @@ -31,15 +31,11 @@ type Resolver struct { func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } func (r *Resolver) Player() generated.PlayerResolver { return &playerResolver{r} } func (r *Resolver) Village() generated.VillageResolver { return &villageResolver{r} } -func (r *Resolver) Tribe() generated.TribeResolver { return &tribeResolver{r} } func (r *Resolver) LiveEnnoblement() generated.LiveEnnoblementResolver { return &liveEnnoblementResolver{r} } func (r *Resolver) Ennoblement() generated.EnnoblementResolver { return &ennoblementResolver{r} } func (r *Resolver) Server() generated.ServerResolver { return &serverResolver{r} } -func (r *Resolver) ServerStatsRecord() generated.ServerStatsRecordResolver { - return &serverStatsRecordResolver{r} -} func (r *Resolver) PlayerHistoryRecord() generated.PlayerHistoryRecordResolver { return &playerHistoryRecordResolver{r} } diff --git a/graphql/resolvers/server.go b/graphql/resolvers/server.go index 04b25bb..59ec522 100644 --- a/graphql/resolvers/server.go +++ b/graphql/resolvers/server.go @@ -2,7 +2,6 @@ package resolvers import ( "context" - "time" "github.com/tribalwarshelp/api/middleware" @@ -19,21 +18,6 @@ func (r *serverResolver) LangVersion(ctx context.Context, obj *models.Server) (* return nil, nil } -func (r *serverResolver) DataUpdatedAt(ctx context.Context, obj *models.Server) (*time.Time, error) { - t := formatDate(ctx, obj.LangVersionTag, obj.DataUpdatedAt) - return &t, nil -} - -func (r *serverResolver) HistoryUpdatedAt(ctx context.Context, obj *models.Server) (*time.Time, error) { - t := formatDate(ctx, obj.LangVersionTag, obj.HistoryUpdatedAt) - return &t, nil -} - -func (r *serverResolver) StatsUpdatedAt(ctx context.Context, obj *models.Server) (*time.Time, error) { - t := formatDate(ctx, obj.LangVersionTag, obj.StatsUpdatedAt) - return &t, nil -} - func (r *queryResolver) Servers(ctx context.Context, filter *models.ServerFilter) (*generated.ServersList, error) { var err error list := &generated.ServersList{} diff --git a/graphql/resolvers/server_stats.go b/graphql/resolvers/server_stats.go index 1e6ebfa..252fe74 100644 --- a/graphql/resolvers/server_stats.go +++ b/graphql/resolvers/server_stats.go @@ -2,19 +2,11 @@ package resolvers import ( "context" - "time" "github.com/tribalwarshelp/api/graphql/generated" - "github.com/tribalwarshelp/api/utils" "github.com/tribalwarshelp/shared/models" ) -func (r *serverStatsRecordResolver) CreatedAt(ctx context.Context, obj *models.ServerStats) (*time.Time, error) { - server, _ := getServer(ctx) - t := formatDate(ctx, utils.LanguageTagFromServerKey(server), obj.CreatedAt) - return &t, nil -} - func (r *Resolver) ServerStats(ctx context.Context, server string, filter *models.ServerStatsFilter) (*generated.ServerStats, error) { var err error list := &generated.ServerStats{} diff --git a/graphql/resolvers/tribe.go b/graphql/resolvers/tribe.go index 4494df8..2ba039c 100644 --- a/graphql/resolvers/tribe.go +++ b/graphql/resolvers/tribe.go @@ -2,19 +2,11 @@ package resolvers import ( "context" - "time" "github.com/tribalwarshelp/api/graphql/generated" - "github.com/tribalwarshelp/api/utils" "github.com/tribalwarshelp/shared/models" ) -func (r *tribeResolver) CreatedAt(ctx context.Context, obj *models.Tribe) (*time.Time, error) { - server, _ := getServer(ctx) - t := formatDate(ctx, utils.LanguageTagFromServerKey(server), obj.CreatedAt) - return &t, nil -} - func (r *queryResolver) Tribes(ctx context.Context, server string, filter *models.TribeFilter) (*generated.TribesList, error) { var err error list := &generated.TribesList{} diff --git a/graphql/resolvers/tribe_history.go b/graphql/resolvers/tribe_history.go index 3e092c8..315778f 100644 --- a/graphql/resolvers/tribe_history.go +++ b/graphql/resolvers/tribe_history.go @@ -2,10 +2,8 @@ package resolvers import ( "context" - "time" "github.com/tribalwarshelp/api/graphql/generated" - "github.com/tribalwarshelp/api/utils" "github.com/tribalwarshelp/shared/models" ) @@ -17,12 +15,6 @@ func (r *tribeHistoryRecordResolver) Tribe(ctx context.Context, obj *models.Trib return getTribe(ctx, obj.TribeID), nil } -func (r *tribeHistoryRecordResolver) CreatedAt(ctx context.Context, obj *models.TribeHistory) (*time.Time, error) { - server, _ := getServer(ctx) - t := formatDate(ctx, utils.LanguageTagFromServerKey(server), obj.CreatedAt) - return &t, nil -} - func (r *Resolver) TribeHistory(ctx context.Context, server string, filter *models.TribeHistoryFilter) (*generated.TribeHistory, error) { var err error list := &generated.TribeHistory{} diff --git a/graphql/schema/ennoblements.graphql b/graphql/schema/ennoblements.graphql index 82ae614..f27c156 100644 --- a/graphql/schema/ennoblements.graphql +++ b/graphql/schema/ennoblements.graphql @@ -4,7 +4,7 @@ type Ennoblement { newOwnerTribe: Tribe @goField(forceResolver: true) oldOwner: Player @goField(forceResolver: true) oldOwnerTribe: Tribe @goField(forceResolver: true) - ennobledAt: Time! @goField(forceResolver: true) + ennobledAt: Time! } type EnnoblementsList { diff --git a/graphql/schema/player.graphql b/graphql/schema/player.graphql index 5e0cb22..5c5a4fe 100644 --- a/graphql/schema/player.graphql +++ b/graphql/schema/player.graphql @@ -14,7 +14,7 @@ type Player { rankTotal: Int! scoreTotal: Int! dailyGrowth: Int! - joinedAt: Time! @goField(forceResolver: true) + joinedAt: Time! tribe: Tribe @goField(forceResolver: true) servers: [String!]! @goField(forceResolver: true) } diff --git a/graphql/schema/player_history.graphql b/graphql/schema/player_history.graphql index e1811e3..0c2ce02 100644 --- a/graphql/schema/player_history.graphql +++ b/graphql/schema/player_history.graphql @@ -12,7 +12,7 @@ type PlayerHistoryRecord { rankTotal: Int! scoreTotal: Int! tribe: Tribe @goField(forceResolver: true) - createdAt: Time! @goField(forceResolver: true) + createdAt: Time! } type PlayerHistory { diff --git a/graphql/schema/server.graphql b/graphql/schema/server.graphql index 9b2f246..cde8434 100644 --- a/graphql/schema/server.graphql +++ b/graphql/schema/server.graphql @@ -16,9 +16,9 @@ type Server { unitConfig: UnitConfig! buildingConfig: BuildingConfig! - dataUpdatedAt: Time! @goField(forceResolver: true) - historyUpdatedAt: Time! @goField(forceResolver: true) - statsUpdatedAt: Time! @goField(forceResolver: true) + dataUpdatedAt: Time! + historyUpdatedAt: Time! + statsUpdatedAt: Time! } type ServersList { diff --git a/graphql/schema/server_stats.graphql b/graphql/schema/server_stats.graphql index ad50d39..7d060ff 100644 --- a/graphql/schema/server_stats.graphql +++ b/graphql/schema/server_stats.graphql @@ -9,7 +9,7 @@ type ServerStatsRecord { barbarianVillages: Int! playerVillages: Int! villages: Int! - createdAt: Time! @goField(forceResolver: true) + createdAt: Time! } type ServerStats { diff --git a/graphql/schema/tribe.graphql b/graphql/schema/tribe.graphql index 787ae5d..ac5e8c9 100644 --- a/graphql/schema/tribe.graphql +++ b/graphql/schema/tribe.graphql @@ -14,7 +14,7 @@ type Tribe { scoreDef: Int! rankTotal: Int! dominance: Float! - createdAt: Time! @goField(forceResolver: true) + createdAt: Time! scoreTotal: Int! } diff --git a/graphql/schema/tribe_history.graphql b/graphql/schema/tribe_history.graphql index 5040e7b..f61c1f0 100644 --- a/graphql/schema/tribe_history.graphql +++ b/graphql/schema/tribe_history.graphql @@ -12,7 +12,7 @@ type TribeHistoryRecord { scoreDef: Int! rankTotal: Int! scoreTotal: Int! - createdAt: Time! @goField(forceResolver: true) + createdAt: Time! } type TribeHistory { diff --git a/langversion/repository.go b/langversion/repository.go index cd52597..76fd4ca 100644 --- a/langversion/repository.go +++ b/langversion/repository.go @@ -6,6 +6,11 @@ import ( "github.com/tribalwarshelp/shared/models" ) -type Repository interface { - Fetch(ctx context.Context, filter *models.LangVersionFilter) ([]*models.LangVersion, int, error) +type FetchConfig struct { + Filter *models.LangVersionFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.LangVersion, int, error) } diff --git a/langversion/repository/pg_repository.go b/langversion/repository/pg_repository.go index 2ef5aa9..c10eb68 100644 --- a/langversion/repository/pg_repository.go +++ b/langversion/repository/pg_repository.go @@ -23,23 +23,28 @@ func NewPGRepository(db *pg.DB) (langversion.Repository, error) { return &pgRepository{db}, nil } -func (repo *pgRepository) Fetch(ctx context.Context, f *models.LangVersionFilter) ([]*models.LangVersion, int, error) { +func (repo *pgRepository) Fetch(ctx context.Context, cfg langversion.FetchConfig) ([]*models.LangVersion, int, error) { var err error data := []*models.LangVersion{} + total := 0 query := repo.Model(&data).Context(ctx) - if f != nil { + if cfg.Filter != nil { query = query. - WhereStruct(f). - Limit(f.Limit). - Offset(f.Offset) + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) - if f.Sort != "" { - query = query.Order(f.Sort) + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) } } - total, err := query.SelectAndCount() + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } if err != nil && err != pg.ErrNoRows { return nil, 0, errors.Wrap(err, "Internal server error") } diff --git a/langversion/usecase/langversion_usecase.go b/langversion/usecase/langversion_usecase.go index 451d359..b89185e 100644 --- a/langversion/usecase/langversion_usecase.go +++ b/langversion/usecase/langversion_usecase.go @@ -28,18 +28,23 @@ func (ucase *usecase) Fetch(ctx context.Context, filter *models.LangVersionFilte filter.Limit = langversion.PaginationLimit } filter.Sort = utils.SanitizeSort(filter.Sort) - return ucase.repo.Fetch(ctx, filter) + 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, total, err := ucase.repo.Fetch(ctx, &models.LangVersionFilter{ - Tag: []models.LanguageTag{tag}, - Limit: 1, + langversions, _, err := ucase.repo.Fetch(ctx, langversion.FetchConfig{ + Filter: &models.LangVersionFilter{ + Tag: []models.LanguageTag{tag}, + Limit: 1, + }, }) if err != nil { return nil, err } - if total == 0 { + if len(langversions) == 0 { return nil, fmt.Errorf("There is no lang version with tag: %s.", tag) } return langversions[0], nil diff --git a/liveennoblement/repository/line_parser.go b/liveennoblement/repository/line_parser.go index 3cc5099..9649ef9 100644 --- a/liveennoblement/repository/line_parser.go +++ b/liveennoblement/repository/line_parser.go @@ -5,8 +5,6 @@ import ( "strconv" "time" - "github.com/tribalwarshelp/api/utils" - "github.com/pkg/errors" "github.com/tribalwarshelp/shared/models" ) @@ -15,11 +13,8 @@ type lineParser struct { location *time.Location } -func newLineParser(timezone string) (*lineParser, error) { - return &lineParser{ - location: utils.GetLocation(timezone), - }, - nil +func newLineParser() *lineParser { + return &lineParser{} } func (parser *lineParser) parse(line []string) (*models.LiveEnnoblement, error) { @@ -36,7 +31,7 @@ func (parser *lineParser) parse(line []string) (*models.LiveEnnoblement, error) if err != nil { return nil, errors.Wrap(err, "timestamp") } - e.EnnobledAt = time.Unix(int64(timestamp), 0).In(parser.location) + e.EnnobledAt = time.Unix(int64(timestamp), 0) e.NewOwnerID, err = strconv.Atoi(line[2]) if err != nil { return nil, errors.Wrap(err, "*models.LiveEnnoblement.NewOwnerID") diff --git a/liveennoblement/repository/pg_repository.go b/liveennoblement/repository/pg_repository.go index ffe5873..d7204e0 100644 --- a/liveennoblement/repository/pg_repository.go +++ b/liveennoblement/repository/pg_repository.go @@ -55,10 +55,7 @@ func (repo *pgRepository) Fetch(ctx context.Context, server string) ([]*models.L } e := []*models.LiveEnnoblement{} - lineParser, err := newLineParser(s.LangVersion.Timezone) - if err != nil { - return nil, err - } + lineParser := newLineParser() for _, line := range lines { ennoblement, err := lineParser.parse(line) if err != nil { diff --git a/main.go b/main.go index 44ee66d..2de174c 100644 --- a/main.go +++ b/main.go @@ -68,14 +68,14 @@ func main() { log.Fatal("Database disconnecting:", err) } }() - //single server redis + redisClient := redis.NewClient(&redis.Options{ Addr: os.Getenv("REDIS_HOST") + ":" + os.Getenv("REDIS_PORT"), Password: os.Getenv("REDIS_PASSWORD"), }) ctx, _ := context.WithTimeout(context.Background(), time.Second*5) if err := redisClient.Ping(ctx).Err(); err != nil { - log.Fatal(errors.Wrap(err, "cannot establish a connection with Redis")) + log.Fatal(errors.Wrap(err, "cannot connect to redis")) } defer func() { if err := redisClient.Close(); err != nil { diff --git a/middleware/dataloaders_to_context.go b/middleware/dataloaders_to_context.go index 4938576..7558e3f 100644 --- a/middleware/dataloaders_to_context.go +++ b/middleware/dataloaders_to_context.go @@ -8,18 +8,21 @@ import ( "github.com/tribalwarshelp/api/graphql/dataloaders" "github.com/tribalwarshelp/api/server" + "github.com/tribalwarshelp/shared/models" "github.com/gin-gonic/gin" ) var serverDataLoadersContextKey ContextKey = "serverDataLoaders" +var langVersionLoadersContextKey ContextKey = "langVersionLoaders" var dataloadersContextKey ContextKey = "dataloaders" func DataLoadersToContext(serverRepo server.Repository, cfg dataloaders.Config) gin.HandlerFunc { return func(c *gin.Context) { ctx := c.Request.Context() - loaders := make(map[string]*dataloaders.ServerDataLoaders) - servers, _, err := serverRepo.Fetch(c.Request.Context(), nil) + serverDataLoaders := make(map[string]*dataloaders.ServerDataLoaders) + langVersionDataLoaders := make(map[models.LanguageTag]*dataloaders.LangVersionDataLoaders) + servers, _, err := serverRepo.Fetch(c.Request.Context(), server.FetchConfig{}) if err != nil { c.JSON(http.StatusOK, &gqlerror.Error{ Message: err.Error(), @@ -28,10 +31,14 @@ func DataLoadersToContext(serverRepo server.Repository, cfg dataloaders.Config) return } for _, server := range servers { - loaders[server.Key] = dataloaders.NewServerDataLoaders(server.Key, cfg) + serverDataLoaders[server.Key] = dataloaders.NewServerDataLoaders(server.Key, cfg) + if _, ok := langVersionDataLoaders[server.LangVersionTag]; !ok { + langVersionDataLoaders[server.LangVersionTag] = dataloaders.NewLangVersionDataLoaders(server.LangVersionTag, cfg) + } } - ctx = StoreServerDataLoadersInContext(ctx, loaders) - ctx = StoreDataLoadersInContext(ctx, dataloaders.New(cfg)) + ctx = StoreServerDataLoadersInContext(ctx, serverDataLoaders) + ctx = StoreLangVersionDataLoadersInContext(ctx, langVersionDataLoaders) + ctx = StoreDataLoadersInContext(ctx, dataloaders.NewDataLoaders(cfg)) c.Request = c.Request.WithContext(ctx) c.Next() } @@ -50,6 +57,19 @@ 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 LangVersionDataLoadersFromContext(ctx context.Context) map[models.LanguageTag]*dataloaders.LangVersionDataLoaders { + dl := ctx.Value(langVersionLoadersContextKey) + if dl == nil { + return nil + } + + return dl.(map[models.LanguageTag]*dataloaders.LangVersionDataLoaders) +} + func StoreDataLoadersInContext(ctx context.Context, loaders *dataloaders.DataLoaders) context.Context { return context.WithValue(ctx, dataloadersContextKey, loaders) } diff --git a/player/repository.go b/player/repository.go index 5622c4a..061a9bd 100644 --- a/player/repository.go +++ b/player/repository.go @@ -6,7 +6,13 @@ import ( "github.com/tribalwarshelp/shared/models" ) -type Repository interface { - Fetch(ctx context.Context, server string, filter *models.PlayerFilter) ([]*models.Player, int, error) - FetchPlayerServers(ctx context.Context, playerID ...int) (map[int][]string, error) +type FetchConfig struct { + Server string + Filter *models.PlayerFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Player, int, error) + FetchPlayerServers(ctx context.Context, langTag models.LanguageTag, playerID ...int) (map[int][]string, error) } diff --git a/player/repository/pg_repository.go b/player/repository/pg_repository.go index 879725e..ec9fa15 100644 --- a/player/repository/pg_repository.go +++ b/player/repository/pg_repository.go @@ -19,33 +19,38 @@ func NewPGRepository(db *pg.DB) player.Repository { return &pgRepository{db} } -func (repo *pgRepository) Fetch(ctx context.Context, server string, f *models.PlayerFilter) ([]*models.Player, int, error) { +func (repo *pgRepository) Fetch(ctx context.Context, cfg player.FetchConfig) ([]*models.Player, int, error) { var err error data := []*models.Player{} - query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx) + total := 0 + query := repo.WithParam("SERVER", pg.Safe(cfg.Server)).Model(&data).Context(ctx) - if f != nil { + if cfg.Filter != nil { query = query. - WhereStruct(f). - Limit(f.Limit). - Offset(f.Offset) + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) - if f.Sort != "" { - query = query.Order(f.Sort) + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) } - if f.Exist != nil { - query = query.Where("exist = ?", *f.Exist) + if cfg.Filter.Exist != nil { + query = query.Where("exist = ?", *cfg.Filter.Exist) } - if f.TribeFilter != nil { - query = query.Relation("Tribe._").WhereStruct(f.TribeFilter) + if cfg.Filter.TribeFilter != nil { + query = query.Relation("Tribe._").WhereStruct(cfg.Filter.TribeFilter) } } - total, err := query.SelectAndCount() + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } if err != nil && err != pg.ErrNoRows { - if strings.Contains(err.Error(), `relation "`+server) { + if strings.Contains(err.Error(), `relation "`+cfg.Server) { return nil, 0, fmt.Errorf("Server not found") } return nil, 0, errors.Wrap(err, "Internal server error") @@ -59,12 +64,14 @@ type fetchPlayerServersQueryResult struct { Servers []string `pg:",array"` } -func (repo *pgRepository) FetchPlayerServers(ctx context.Context, playerID ...int) (map[int][]string, error) { +func (repo *pgRepository) FetchPlayerServers(ctx context.Context, langTag models.LanguageTag, 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("player_id IN (?)", pg.In(playerID)). Group("player_id"). Select(&data); err != nil && err != pg.ErrNoRows { diff --git a/player/usecase/player_usecase.go b/player/usecase/player_usecase.go index 27da675..32e2233 100644 --- a/player/usecase/player_usecase.go +++ b/player/usecase/player_usecase.go @@ -25,18 +25,25 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.P filter.Limit = player.PaginationLimit } filter.Sort = utils.SanitizeSort(filter.Sort) - return ucase.repo.Fetch(ctx, server, filter) + return ucase.repo.Fetch(ctx, player.FetchConfig{ + Server: server, + Filter: filter, + Count: true, + }) } func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*models.Player, error) { - players, total, err := ucase.repo.Fetch(ctx, server, &models.PlayerFilter{ - ID: []int{id}, - Limit: 1, + players, _, err := ucase.repo.Fetch(ctx, player.FetchConfig{ + Server: server, + Filter: &models.PlayerFilter{ + ID: []int{id}, + Limit: 1, + }, }) if err != nil { return nil, err } - if total == 0 { + if len(players) == 0 { return nil, fmt.Errorf("Player (ID: %d) not found.", id) } return players[0], nil diff --git a/playerhistory/repository.go b/playerhistory/repository.go index f98f804..775971a 100644 --- a/playerhistory/repository.go +++ b/playerhistory/repository.go @@ -6,6 +6,12 @@ import ( "github.com/tribalwarshelp/shared/models" ) -type Repository interface { - Fetch(ctx context.Context, server string, filter *models.PlayerHistoryFilter) ([]*models.PlayerHistory, int, error) +type FetchConfig struct { + Server string + Filter *models.PlayerHistoryFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.PlayerHistory, int, error) } diff --git a/playerhistory/repository/pg_repository.go b/playerhistory/repository/pg_repository.go index e61499f..c6fb096 100644 --- a/playerhistory/repository/pg_repository.go +++ b/playerhistory/repository/pg_repository.go @@ -19,25 +19,30 @@ func NewPGRepository(db *pg.DB) playerhistory.Repository { return &pgRepository{db} } -func (repo *pgRepository) Fetch(ctx context.Context, server string, f *models.PlayerHistoryFilter) ([]*models.PlayerHistory, int, error) { +func (repo *pgRepository) Fetch(ctx context.Context, cfg playerhistory.FetchConfig) ([]*models.PlayerHistory, int, error) { var err error + total := 0 data := []*models.PlayerHistory{} - query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx) + query := repo.WithParam("SERVER", pg.Safe(cfg.Server)).Model(&data).Context(ctx) - if f != nil { + if cfg.Filter != nil { query = query. - WhereStruct(f). - Limit(f.Limit). - Offset(f.Offset) + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) - if f.Sort != "" { - query = query.Order(f.Sort) + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) } } - total, err := query.SelectAndCount() + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } if err != nil && err != pg.ErrNoRows { - if strings.Contains(err.Error(), `relation "`+server) { + if strings.Contains(err.Error(), `relation "`+cfg.Server) { return nil, 0, fmt.Errorf("Server not found") } return nil, 0, errors.Wrap(err, "Internal server error") diff --git a/playerhistory/usecase/playerhistory_usecase.go b/playerhistory/usecase/playerhistory_usecase.go index 01f9e98..311c257 100644 --- a/playerhistory/usecase/playerhistory_usecase.go +++ b/playerhistory/usecase/playerhistory_usecase.go @@ -24,5 +24,9 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.P filter.Limit = playerhistory.PaginationLimit } filter.Sort = utils.SanitizeSort(filter.Sort) - return ucase.repo.Fetch(ctx, server, filter) + return ucase.repo.Fetch(ctx, playerhistory.FetchConfig{ + Server: server, + Filter: filter, + Count: true, + }) } diff --git a/server/repository.go b/server/repository.go index 9decf22..e82dbda 100644 --- a/server/repository.go +++ b/server/repository.go @@ -6,6 +6,11 @@ import ( "github.com/tribalwarshelp/shared/models" ) -type Repository interface { - Fetch(ctx context.Context, filter *models.ServerFilter) ([]*models.Server, int, error) +type FetchConfig struct { + Filter *models.ServerFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Server, int, error) } diff --git a/server/repository/pg_repository.go b/server/repository/pg_repository.go index 848bb83..cde1601 100644 --- a/server/repository/pg_repository.go +++ b/server/repository/pg_repository.go @@ -23,23 +23,28 @@ func NewPGRepository(db *pg.DB) (server.Repository, error) { return &pgRepository{db}, nil } -func (repo *pgRepository) Fetch(ctx context.Context, f *models.ServerFilter) ([]*models.Server, int, error) { +func (repo *pgRepository) Fetch(ctx context.Context, cfg server.FetchConfig) ([]*models.Server, int, error) { var err error + total := 0 data := []*models.Server{} query := repo.Model(&data).Context(ctx) - if f != nil { + if cfg.Filter != nil { query = query. - WhereStruct(f). - Limit(f.Limit). - Offset(f.Offset) + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) - if f.Sort != "" { - query = query.Order(f.Sort) + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) } } - total, err := query.SelectAndCount() + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } if err != nil && err != pg.ErrNoRows { return nil, 0, errors.Wrap(err, "Internal server error") } diff --git a/server/usecase/server_usecase.go b/server/usecase/server_usecase.go index 9f3b82b..c700d10 100644 --- a/server/usecase/server_usecase.go +++ b/server/usecase/server_usecase.go @@ -25,18 +25,23 @@ func (ucase *usecase) Fetch(ctx context.Context, filter *models.ServerFilter) ([ filter.Limit = server.PaginationLimit } filter.Sort = utils.SanitizeSort(filter.Sort) - return ucase.repo.Fetch(ctx, filter) + return ucase.repo.Fetch(ctx, server.FetchConfig{ + Count: true, + Filter: filter, + }) } func (ucase *usecase) GetByKey(ctx context.Context, key string) (*models.Server, error) { - servers, total, err := ucase.repo.Fetch(ctx, &models.ServerFilter{ - Key: []string{key}, - Limit: 1, + servers, _, err := ucase.repo.Fetch(ctx, server.FetchConfig{ + Filter: &models.ServerFilter{ + Key: []string{key}, + Limit: 1, + }, }) if err != nil { return nil, err } - if total == 0 { + if len(servers) == 0 { return nil, fmt.Errorf("Server (key: %s) not found.", key) } return servers[0], nil diff --git a/serverstats/repository.go b/serverstats/repository.go index 2495c87..6702e12 100644 --- a/serverstats/repository.go +++ b/serverstats/repository.go @@ -6,6 +6,12 @@ import ( "github.com/tribalwarshelp/shared/models" ) -type Repository interface { - Fetch(ctx context.Context, server string, filter *models.ServerStatsFilter) ([]*models.ServerStats, int, error) +type FetchConfig struct { + Server string + Filter *models.ServerStatsFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.ServerStats, int, error) } diff --git a/serverstats/repository/pg_repository.go b/serverstats/repository/pg_repository.go index 3efbbd9..8d71e8c 100644 --- a/serverstats/repository/pg_repository.go +++ b/serverstats/repository/pg_repository.go @@ -19,25 +19,30 @@ func NewPGRepository(db *pg.DB) serverstats.Repository { return &pgRepository{db} } -func (repo *pgRepository) Fetch(ctx context.Context, server string, f *models.ServerStatsFilter) ([]*models.ServerStats, int, error) { +func (repo *pgRepository) Fetch(ctx context.Context, cfg serverstats.FetchConfig) ([]*models.ServerStats, int, error) { var err error data := []*models.ServerStats{} - query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx) + total := 0 + query := repo.WithParam("SERVER", pg.Safe(cfg.Server)).Model(&data).Context(ctx) - if f != nil { + if cfg.Filter != nil { query = query. - WhereStruct(f). - Limit(f.Limit). - Offset(f.Offset) + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) - if f.Sort != "" { - query = query.Order(f.Sort) + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) } } - total, err := query.SelectAndCount() + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } if err != nil && err != pg.ErrNoRows { - if strings.Contains(err.Error(), `relation "`+server) { + if strings.Contains(err.Error(), `relation "`+cfg.Server) { return nil, 0, fmt.Errorf("Server not found") } return nil, 0, errors.Wrap(err, "Internal server error") diff --git a/serverstats/usecase/serverstats_usecase.go b/serverstats/usecase/serverstats_usecase.go index 2b17602..3d1c051 100644 --- a/serverstats/usecase/serverstats_usecase.go +++ b/serverstats/usecase/serverstats_usecase.go @@ -24,5 +24,9 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.S filter.Limit = serverstats.PaginationLimit } filter.Sort = utils.SanitizeSort(filter.Sort) - return ucase.repo.Fetch(ctx, server, filter) + return ucase.repo.Fetch(ctx, serverstats.FetchConfig{ + Server: server, + Filter: filter, + Count: true, + }) } diff --git a/tribe/repository.go b/tribe/repository.go index 9aa6d26..a152f60 100644 --- a/tribe/repository.go +++ b/tribe/repository.go @@ -6,6 +6,12 @@ import ( "github.com/tribalwarshelp/shared/models" ) -type Repository interface { - Fetch(ctx context.Context, server string, filter *models.TribeFilter) ([]*models.Tribe, int, error) +type FetchConfig struct { + Server string + Filter *models.TribeFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.Tribe, int, error) } diff --git a/tribe/repository/pg_repository.go b/tribe/repository/pg_repository.go index afed28c..1c50030 100644 --- a/tribe/repository/pg_repository.go +++ b/tribe/repository/pg_repository.go @@ -19,29 +19,34 @@ func NewPGRepository(db *pg.DB) tribe.Repository { return &pgRepository{db} } -func (repo *pgRepository) Fetch(ctx context.Context, server string, f *models.TribeFilter) ([]*models.Tribe, int, error) { +func (repo *pgRepository) Fetch(ctx context.Context, cfg tribe.FetchConfig) ([]*models.Tribe, int, error) { var err error data := []*models.Tribe{} - query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx) + total := 0 + query := repo.WithParam("SERVER", pg.Safe(cfg.Server)).Model(&data).Context(ctx) - if f != nil { + if cfg.Filter != nil { query = query. - WhereStruct(f). - Limit(f.Limit). - Offset(f.Offset) + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) - if f.Sort != "" { - query = query.Order(f.Sort) + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) } - if f.Exist != nil { - query = query.Where("exist = ?", *f.Exist) + if cfg.Filter.Exist != nil { + query = query.Where("exist = ?", *cfg.Filter.Exist) } } - total, err := query.SelectAndCount() + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } if err != nil && err != pg.ErrNoRows { - if strings.Contains(err.Error(), `relation "`+server) { + if strings.Contains(err.Error(), `relation "`+cfg.Server) { return nil, 0, fmt.Errorf("Server not found") } return nil, 0, errors.Wrap(err, "Internal server error") diff --git a/tribe/usecase/tribe_usecase.go b/tribe/usecase/tribe_usecase.go index 2126db4..9ca083f 100644 --- a/tribe/usecase/tribe_usecase.go +++ b/tribe/usecase/tribe_usecase.go @@ -25,18 +25,25 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.T filter.Limit = tribe.PaginationLimit } filter.Sort = utils.SanitizeSort(filter.Sort) - return ucase.repo.Fetch(ctx, server, filter) + return ucase.repo.Fetch(ctx, tribe.FetchConfig{ + Filter: filter, + Server: server, + Count: true, + }) } func (ucase *usecase) GetByID(ctx context.Context, server string, id int) (*models.Tribe, error) { - tribes, total, err := ucase.repo.Fetch(ctx, server, &models.TribeFilter{ - ID: []int{id}, - Limit: 1, + tribes, _, err := ucase.repo.Fetch(ctx, tribe.FetchConfig{ + Filter: &models.TribeFilter{ + ID: []int{id}, + Limit: 1, + }, + Server: server, }) if err != nil { return nil, err } - if total == 0 { + if len(tribes) == 0 { return nil, fmt.Errorf("Tribe (ID: %s) not found.", id) } return tribes[0], nil diff --git a/tribehistory/repository.go b/tribehistory/repository.go index 9b0fdd4..9cdf02f 100644 --- a/tribehistory/repository.go +++ b/tribehistory/repository.go @@ -6,6 +6,12 @@ import ( "github.com/tribalwarshelp/shared/models" ) -type Repository interface { - Fetch(ctx context.Context, server string, filter *models.TribeHistoryFilter) ([]*models.TribeHistory, int, error) +type FetchConfig struct { + Server string + Filter *models.TribeHistoryFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.TribeHistory, int, error) } diff --git a/tribehistory/repository/pg_repository.go b/tribehistory/repository/pg_repository.go index 749d3a1..98b88e1 100644 --- a/tribehistory/repository/pg_repository.go +++ b/tribehistory/repository/pg_repository.go @@ -19,25 +19,30 @@ func NewPGRepository(db *pg.DB) tribehistory.Repository { return &pgRepository{db} } -func (repo *pgRepository) Fetch(ctx context.Context, server string, f *models.TribeHistoryFilter) ([]*models.TribeHistory, int, error) { +func (repo *pgRepository) Fetch(ctx context.Context, cfg tribehistory.FetchConfig) ([]*models.TribeHistory, int, error) { var err error + total := 0 data := []*models.TribeHistory{} - query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx) + query := repo.WithParam("SERVER", pg.Safe(cfg.Server)).Model(&data).Context(ctx) - if f != nil { + if cfg.Filter != nil { query = query. - WhereStruct(f). - Limit(f.Limit). - Offset(f.Offset) + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) - if f.Sort != "" { - query = query.Order(f.Sort) + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) } } - total, err := query.SelectAndCount() + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } if err != nil && err != pg.ErrNoRows { - if strings.Contains(err.Error(), `relation "`+server) { + if strings.Contains(err.Error(), `relation "`+cfg.Server) { return nil, 0, fmt.Errorf("Server not found") } return nil, 0, errors.Wrap(err, "Internal server error") diff --git a/tribehistory/usecase/tribehistory_usecase.go b/tribehistory/usecase/tribehistory_usecase.go index a55fd79..c1c0e9b 100644 --- a/tribehistory/usecase/tribehistory_usecase.go +++ b/tribehistory/usecase/tribehistory_usecase.go @@ -24,5 +24,9 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.T filter.Limit = tribehistory.PaginationLimit } filter.Sort = utils.SanitizeSort(filter.Sort) - return ucase.repo.Fetch(ctx, server, filter) + return ucase.repo.Fetch(ctx, tribehistory.FetchConfig{ + Server: server, + Filter: filter, + Count: true, + }) } diff --git a/utils/get_location.go b/utils/get_location.go index d48a16b..81eb697 100644 --- a/utils/get_location.go +++ b/utils/get_location.go @@ -1,6 +1,8 @@ package utils -import "time" +import ( + "time" +) func GetLocation(timezone string) *time.Location { loc, err := time.LoadLocation(timezone) From ebc2b950020a3a3e2663244e579c6225793b116f Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Wed, 24 Jun 2020 15:25:31 +0200 Subject: [PATCH 2/5] add tribechange usecase, repository, resolver --- go.mod | 2 +- go.sum | 2 + graphql/generated/generated.go | 645 +++++++++++++++++++++ graphql/generated/models.go | 5 + graphql/gqlgen.yml | 4 + graphql/resolvers/resolver.go | 6 + graphql/resolvers/tribe_change.go | 39 ++ graphql/schema/tribe_change.graphql | 36 ++ main.go | 9 +- tribechange/constants.go | 5 + tribechange/repository.go | 17 + tribechange/repository/pg_repository.go | 52 ++ tribechange/usecase.go | 11 + tribechange/usecase/tribechange_usecase.go | 32 + 14 files changed, 862 insertions(+), 3 deletions(-) create mode 100644 graphql/resolvers/tribe_change.go create mode 100644 graphql/schema/tribe_change.graphql create mode 100644 tribechange/constants.go create mode 100644 tribechange/repository.go create mode 100644 tribechange/repository/pg_repository.go create mode 100644 tribechange/usecase.go create mode 100644 tribechange/usecase/tribechange_usecase.go diff --git a/go.mod b/go.mod index 3c5d45e..1fab6ca 100644 --- a/go.mod +++ b/go.mod @@ -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-20200623144748-aa834a01dce6 + github.com/tribalwarshelp/shared v0.0.0-20200624131453-e04f1de1bf5c 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 diff --git a/go.sum b/go.sum index d87d8b5..737b4e1 100644 --- a/go.sum +++ b/go.sum @@ -177,6 +177,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-20200623144748-aa834a01dce6 h1:WZ1oxHysFtiPjHa2ADUqiGrzwcN3j0YpiVg/V2e/74o= 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/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= diff --git a/graphql/generated/generated.go b/graphql/generated/generated.go index e35a069..0df3d7e 100644 --- a/graphql/generated/generated.go +++ b/graphql/generated/generated.go @@ -42,6 +42,7 @@ type ResolverRoot interface { PlayerHistoryRecord() PlayerHistoryRecordResolver Query() QueryResolver Server() ServerResolver + TribeChangeRecord() TribeChangeRecordResolver TribeHistoryRecord() TribeHistoryRecordResolver Village() VillageResolver } @@ -178,6 +179,7 @@ type ComplexityRoot struct { ServerStats func(childComplexity int, server string, filter *models.ServerStatsFilter) int Servers func(childComplexity int, filter *models.ServerFilter) int Tribe func(childComplexity int, server string, id int) int + TribeChanges func(childComplexity int, server string, filter *models.TribeChangeFilter) int TribeHistory func(childComplexity int, server string, filter *models.TribeHistoryFilter) int Tribes func(childComplexity int, server string, filter *models.TribeFilter) int Village func(childComplexity int, server string, id int) int @@ -393,6 +395,18 @@ type ComplexityRoot struct { TotalVillages func(childComplexity int) int } + TribeChangeRecord struct { + CreatedAt func(childComplexity int) int + NewTribe func(childComplexity int) int + OldTribe func(childComplexity int) int + Player func(childComplexity int) int + } + + TribeChanges struct { + Items func(childComplexity int) int + Total func(childComplexity int) int + } + TribeHistory struct { Items func(childComplexity int) int Total func(childComplexity int) int @@ -497,6 +511,7 @@ type QueryResolver interface { ServerStats(ctx context.Context, server string, filter *models.ServerStatsFilter) (*ServerStats, error) Tribes(ctx context.Context, server string, filter *models.TribeFilter) (*TribesList, error) Tribe(ctx context.Context, server string, id int) (*models.Tribe, error) + TribeChanges(ctx context.Context, server string, filter *models.TribeChangeFilter) (*TribeChanges, error) TribeHistory(ctx context.Context, server string, filter *models.TribeHistoryFilter) (*TribeHistory, error) Villages(ctx context.Context, server string, filter *models.VillageFilter) (*VillagesList, error) Village(ctx context.Context, server string, id int) (*models.Village, error) @@ -504,6 +519,11 @@ type QueryResolver interface { type ServerResolver interface { LangVersion(ctx context.Context, obj *models.Server) (*models.LangVersion, error) } +type TribeChangeRecordResolver interface { + Player(ctx context.Context, obj *models.TribeChange) (*models.Player, error) + OldTribe(ctx context.Context, obj *models.TribeChange) (*models.Tribe, error) + NewTribe(ctx context.Context, obj *models.TribeChange) (*models.Tribe, error) +} type TribeHistoryRecordResolver interface { Tribe(ctx context.Context, obj *models.TribeHistory) (*models.Tribe, error) } @@ -1239,6 +1259,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Tribe(childComplexity, args["server"].(string), args["id"].(int)), true + case "Query.tribeChanges": + if e.complexity.Query.TribeChanges == nil { + break + } + + args, err := ec.field_Query_tribeChanges_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.TribeChanges(childComplexity, args["server"].(string), args["filter"].(*models.TribeChangeFilter)), true + case "Query.tribeHistory": if e.complexity.Query.TribeHistory == nil { break @@ -2351,6 +2383,48 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Tribe.TotalVillages(childComplexity), true + case "TribeChangeRecord.createdAt": + if e.complexity.TribeChangeRecord.CreatedAt == nil { + break + } + + return e.complexity.TribeChangeRecord.CreatedAt(childComplexity), true + + case "TribeChangeRecord.newTribe": + if e.complexity.TribeChangeRecord.NewTribe == nil { + break + } + + return e.complexity.TribeChangeRecord.NewTribe(childComplexity), true + + case "TribeChangeRecord.oldTribe": + if e.complexity.TribeChangeRecord.OldTribe == nil { + break + } + + return e.complexity.TribeChangeRecord.OldTribe(childComplexity), true + + case "TribeChangeRecord.player": + if e.complexity.TribeChangeRecord.Player == nil { + break + } + + return e.complexity.TribeChangeRecord.Player(childComplexity), true + + case "TribeChanges.items": + if e.complexity.TribeChanges.Items == nil { + break + } + + return e.complexity.TribeChanges.Items(childComplexity), true + + case "TribeChanges.total": + if e.complexity.TribeChanges.Total == nil { + break + } + + return e.complexity.TribeChanges.Total(childComplexity), true + case "TribeHistory.items": if e.complexity.TribeHistory.Items == nil { break @@ -3402,6 +3476,43 @@ extend type Query { tribes(server: String!, filter: TribeFilter): TribesList! tribe(server: String!, id: Int!): Tribe } +`, BuiltIn: false}, + &ast.Source{Name: "schema/tribe_change.graphql", Input: `type TribeChangeRecord { + player: Player @goField(forceResolver: true) + oldTribe: Tribe @goField(forceResolver: true) + newTribe: Tribe @goField(forceResolver: true) + createdAt: Time! +} + +type TribeChanges { + total: Int! + items: [TribeChangeRecord!] +} + +input TribeChangeFilter { + playerID: [Int!] + playerIDNEQ: [Int!] + + oldTribeID: [Int!] + oldTribeIDNEQ: [Int!] + + newTribeID: [Int!] + newTribeIDNEQ: [Int!] + + createdAt: Time + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + offset: Int + limit: Int + sort: String +} + +extend type Query { + tribeChanges(server: String!, filter: TribeChangeFilter): TribeChanges! +} `, BuiltIn: false}, &ast.Source{Name: "schema/tribe_history.graphql", Input: `type TribeHistoryRecord { tribe: Tribe @goField(forceResolver: true) @@ -3730,6 +3841,28 @@ func (ec *executionContext) field_Query_servers_args(ctx context.Context, rawArg return args, nil } +func (ec *executionContext) field_Query_tribeChanges_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["server"]; ok { + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["server"] = arg0 + var arg1 *models.TribeChangeFilter + if tmp, ok := rawArgs["filter"]; ok { + arg1, err = ec.unmarshalOTribeChangeFilter2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeChangeFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg1 + return args, nil +} + func (ec *executionContext) field_Query_tribeHistory_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -7130,6 +7263,47 @@ func (ec *executionContext) _Query_tribe(ctx context.Context, field graphql.Coll return ec.marshalOTribe2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribe(ctx, field.Selections, res) } +func (ec *executionContext) _Query_tribeChanges(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_tribeChanges_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().TribeChanges(rctx, args["server"].(string), args["filter"].(*models.TribeChangeFilter)) + }) + 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.(*TribeChanges) + fc.Result = res + return ec.marshalNTribeChanges2ᚖgithubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐTribeChanges(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_tribeHistory(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -12478,6 +12652,198 @@ func (ec *executionContext) _Tribe_scoreTotal(ctx context.Context, field graphql return ec.marshalNInt2int(ctx, field.Selections, res) } +func (ec *executionContext) _TribeChangeRecord_player(ctx context.Context, field graphql.CollectedField, obj *models.TribeChange) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "TribeChangeRecord", + 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.TribeChangeRecord().Player(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*models.Player) + fc.Result = res + return ec.marshalOPlayer2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐPlayer(ctx, field.Selections, res) +} + +func (ec *executionContext) _TribeChangeRecord_oldTribe(ctx context.Context, field graphql.CollectedField, obj *models.TribeChange) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "TribeChangeRecord", + 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.TribeChangeRecord().OldTribe(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*models.Tribe) + fc.Result = res + return ec.marshalOTribe2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribe(ctx, field.Selections, res) +} + +func (ec *executionContext) _TribeChangeRecord_newTribe(ctx context.Context, field graphql.CollectedField, obj *models.TribeChange) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "TribeChangeRecord", + 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.TribeChangeRecord().NewTribe(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*models.Tribe) + fc.Result = res + return ec.marshalOTribe2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribe(ctx, field.Selections, res) +} + +func (ec *executionContext) _TribeChangeRecord_createdAt(ctx context.Context, field graphql.CollectedField, obj *models.TribeChange) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "TribeChangeRecord", + 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.CreatedAt, 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) _TribeChanges_total(ctx context.Context, field graphql.CollectedField, obj *TribeChanges) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "TribeChanges", + 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.Total, 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) _TribeChanges_items(ctx context.Context, field graphql.CollectedField, obj *TribeChanges) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "TribeChanges", + 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.Items, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*models.TribeChange) + fc.Result = res + return ec.marshalOTribeChangeRecord2ᚕᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeChangeᚄ(ctx, field.Selections, res) +} + func (ec *executionContext) _TribeHistory_total(ctx context.Context, field graphql.CollectedField, obj *TribeHistory) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -16020,6 +16386,102 @@ func (ec *executionContext) unmarshalInputServerStatsFilter(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputTribeChangeFilter(ctx context.Context, obj interface{}) (models.TribeChangeFilter, error) { + var it models.TribeChangeFilter + var asMap = obj.(map[string]interface{}) + + for k, v := range asMap { + switch k { + case "playerID": + var err error + it.PlayerID, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "playerIDNEQ": + var err error + it.PlayerIdNEQ, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "oldTribeID": + var err error + it.OldTribeID, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "oldTribeIDNEQ": + var err error + it.OldTribeIdNEQ, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "newTribeID": + var err error + it.NewTribeID, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "newTribeIDNEQ": + var err error + it.NewTribeIdNEQ, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "createdAt": + var err error + it.CreatedAt, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtGT": + var err error + it.CreatedAtGT, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtGTE": + var err error + it.CreatedAtGTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtLT": + var err error + it.CreatedAtLT, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtLTE": + var err error + it.CreatedAtLTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "offset": + var err error + it.Offset, err = ec.unmarshalOInt2int(ctx, v) + if err != nil { + return it, err + } + case "limit": + var err error + it.Limit, err = ec.unmarshalOInt2int(ctx, v) + if err != nil { + return it, err + } + case "sort": + var err error + it.Sort, err = ec.unmarshalOString2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputTribeFilter(ctx context.Context, obj interface{}) (models.TribeFilter, error) { var it models.TribeFilter var asMap = obj.(map[string]interface{}) @@ -17660,6 +18122,20 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_tribe(ctx, field) return res }) + case "tribeChanges": + 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._Query_tribeChanges(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "tribeHistory": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -18892,6 +19368,95 @@ func (ec *executionContext) _Tribe(ctx context.Context, sel ast.SelectionSet, ob return out } +var tribeChangeRecordImplementors = []string{"TribeChangeRecord"} + +func (ec *executionContext) _TribeChangeRecord(ctx context.Context, sel ast.SelectionSet, obj *models.TribeChange) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, tribeChangeRecordImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("TribeChangeRecord") + case "player": + 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._TribeChangeRecord_player(ctx, field, obj) + return res + }) + case "oldTribe": + 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._TribeChangeRecord_oldTribe(ctx, field, obj) + return res + }) + case "newTribe": + 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._TribeChangeRecord_newTribe(ctx, field, obj) + return res + }) + case "createdAt": + out.Values[i] = ec._TribeChangeRecord_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var tribeChangesImplementors = []string{"TribeChanges"} + +func (ec *executionContext) _TribeChanges(ctx context.Context, sel ast.SelectionSet, obj *TribeChanges) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, tribeChangesImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("TribeChanges") + case "total": + out.Values[i] = ec._TribeChanges_total(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "items": + out.Values[i] = ec._TribeChanges_items(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var tribeHistoryImplementors = []string{"TribeHistory"} func (ec *executionContext) _TribeHistory(ctx context.Context, sel ast.SelectionSet, obj *TribeHistory) graphql.Marshaler { @@ -19929,6 +20494,34 @@ func (ec *executionContext) marshalNTribe2ᚖgithubᚗcomᚋtribalwarshelpᚋsha return ec._Tribe(ctx, sel, v) } +func (ec *executionContext) marshalNTribeChangeRecord2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeChange(ctx context.Context, sel ast.SelectionSet, v models.TribeChange) graphql.Marshaler { + return ec._TribeChangeRecord(ctx, sel, &v) +} + +func (ec *executionContext) marshalNTribeChangeRecord2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeChange(ctx context.Context, sel ast.SelectionSet, v *models.TribeChange) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._TribeChangeRecord(ctx, sel, v) +} + +func (ec *executionContext) marshalNTribeChanges2githubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐTribeChanges(ctx context.Context, sel ast.SelectionSet, v TribeChanges) graphql.Marshaler { + return ec._TribeChanges(ctx, sel, &v) +} + +func (ec *executionContext) marshalNTribeChanges2ᚖgithubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐTribeChanges(ctx context.Context, sel ast.SelectionSet, v *TribeChanges) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._TribeChanges(ctx, sel, v) +} + func (ec *executionContext) marshalNTribeHistory2githubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐTribeHistory(ctx context.Context, sel ast.SelectionSet, v TribeHistory) graphql.Marshaler { return ec._TribeHistory(ctx, sel, &v) } @@ -20915,6 +21508,58 @@ func (ec *executionContext) marshalOTribe2ᚖgithubᚗcomᚋtribalwarshelpᚋsha return ec._Tribe(ctx, sel, v) } +func (ec *executionContext) unmarshalOTribeChangeFilter2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeChangeFilter(ctx context.Context, v interface{}) (models.TribeChangeFilter, error) { + return ec.unmarshalInputTribeChangeFilter(ctx, v) +} + +func (ec *executionContext) unmarshalOTribeChangeFilter2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeChangeFilter(ctx context.Context, v interface{}) (*models.TribeChangeFilter, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalOTribeChangeFilter2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeChangeFilter(ctx, v) + return &res, err +} + +func (ec *executionContext) marshalOTribeChangeRecord2ᚕᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeChangeᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.TribeChange) graphql.Marshaler { + if v == nil { + return graphql.Null + } + 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.marshalNTribeChangeRecord2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeChange(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + return ret +} + func (ec *executionContext) unmarshalOTribeFilter2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribeFilter(ctx context.Context, v interface{}) (models.TribeFilter, error) { return ec.unmarshalInputTribeFilter(ctx, v) } diff --git a/graphql/generated/models.go b/graphql/generated/models.go index c237362..6dcbfad 100644 --- a/graphql/generated/models.go +++ b/graphql/generated/models.go @@ -36,6 +36,11 @@ type ServersList struct { Total int `json:"total"` } +type TribeChanges struct { + Total int `json:"total"` + Items []*models.TribeChange `json:"items"` +} + type TribeHistory struct { Total int `json:"total"` Items []*models.TribeHistory `json:"items"` diff --git a/graphql/gqlgen.yml b/graphql/gqlgen.yml index 7759229..1f5b18d 100644 --- a/graphql/gqlgen.yml +++ b/graphql/gqlgen.yml @@ -90,3 +90,7 @@ models: model: github.com/tribalwarshelp/shared/models.ServerStats ServerStatsFilter: model: github.com/tribalwarshelp/shared/models.ServerStatsFilter + TribeChangeRecord: + model: github.com/tribalwarshelp/shared/models.TribeChange + TribeChangeFilter: + model: github.com/tribalwarshelp/shared/models.TribeChangeFilter diff --git a/graphql/resolvers/resolver.go b/graphql/resolvers/resolver.go index 41946fe..2481600 100644 --- a/graphql/resolvers/resolver.go +++ b/graphql/resolvers/resolver.go @@ -10,6 +10,7 @@ import ( "github.com/tribalwarshelp/api/server" "github.com/tribalwarshelp/api/serverstats" "github.com/tribalwarshelp/api/tribe" + "github.com/tribalwarshelp/api/tribechange" "github.com/tribalwarshelp/api/tribehistory" "github.com/tribalwarshelp/api/village" ) @@ -25,6 +26,7 @@ type Resolver struct { PlayerHistoryUcase playerhistory.Usecase TribeHistoryUcase tribehistory.Usecase ServerStatsUcase serverstats.Usecase + TribeChangeUcase tribechange.Usecase } // Query returns generated.QueryResolver implementation. @@ -42,6 +44,9 @@ func (r *Resolver) PlayerHistoryRecord() generated.PlayerHistoryRecordResolver { func (r *Resolver) TribeHistoryRecord() generated.TribeHistoryRecordResolver { return &tribeHistoryRecordResolver{r} } +func (r *Resolver) TribeChangeRecord() generated.TribeChangeRecordResolver { + return &tribeChangeRecordResolver{r} +} type queryResolver struct{ *Resolver } type playerResolver struct{ *Resolver } @@ -53,3 +58,4 @@ type serverResolver struct{ *Resolver } type playerHistoryRecordResolver struct{ *Resolver } type tribeHistoryRecordResolver struct{ *Resolver } type serverStatsRecordResolver struct{ *Resolver } +type tribeChangeRecordResolver struct{ *Resolver } diff --git a/graphql/resolvers/tribe_change.go b/graphql/resolvers/tribe_change.go new file mode 100644 index 0000000..305eefd --- /dev/null +++ b/graphql/resolvers/tribe_change.go @@ -0,0 +1,39 @@ +package resolvers + +import ( + "context" + + "github.com/tribalwarshelp/api/graphql/generated" + "github.com/tribalwarshelp/shared/models" +) + +func (r *tribeChangeRecordResolver) Player(ctx context.Context, obj *models.TribeChange) (*models.Player, error) { + if obj.Player != nil { + return obj.Player, nil + } + + return getPlayer(ctx, obj.PlayerID), nil +} + +func (r *tribeChangeRecordResolver) NewTribe(ctx context.Context, obj *models.TribeChange) (*models.Tribe, error) { + if obj.NewTribe != nil { + return obj.NewTribe, nil + } + + return getTribe(ctx, obj.NewTribeID), nil +} + +func (r *tribeChangeRecordResolver) OldTribe(ctx context.Context, obj *models.TribeChange) (*models.Tribe, error) { + if obj.OldTribe != nil { + return obj.OldTribe, nil + } + + return getTribe(ctx, obj.OldTribeID), nil +} + +func (r *Resolver) TribeChanges(ctx context.Context, server string, filter *models.TribeChangeFilter) (*generated.TribeChanges, error) { + var err error + list := &generated.TribeChanges{} + list.Items, list.Total, err = r.TribeChangeUcase.Fetch(ctx, server, filter) + return list, err +} diff --git a/graphql/schema/tribe_change.graphql b/graphql/schema/tribe_change.graphql new file mode 100644 index 0000000..d8e10ce --- /dev/null +++ b/graphql/schema/tribe_change.graphql @@ -0,0 +1,36 @@ +type TribeChangeRecord { + player: Player @goField(forceResolver: true) + oldTribe: Tribe @goField(forceResolver: true) + newTribe: Tribe @goField(forceResolver: true) + createdAt: Time! +} + +type TribeChanges { + total: Int! + items: [TribeChangeRecord!] +} + +input TribeChangeFilter { + playerID: [Int!] + playerIDNEQ: [Int!] + + oldTribeID: [Int!] + oldTribeIDNEQ: [Int!] + + newTribeID: [Int!] + newTribeIDNEQ: [Int!] + + createdAt: Time + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + offset: Int + limit: Int + sort: String +} + +extend type Query { + tribeChanges(server: String!, filter: TribeChangeFilter): TribeChanges! +} diff --git a/main.go b/main.go index 2de174c..0e0907b 100644 --- a/main.go +++ b/main.go @@ -37,6 +37,8 @@ import ( serverstatsucase "github.com/tribalwarshelp/api/serverstats/usecase" triberepo "github.com/tribalwarshelp/api/tribe/repository" tribeucase "github.com/tribalwarshelp/api/tribe/usecase" + tribechangerepo "github.com/tribalwarshelp/api/tribechange/repository" + tribechangeucase "github.com/tribalwarshelp/api/tribechange/usecase" tribehistoryrepo "github.com/tribalwarshelp/api/tribehistory/repository" tribehistoryucase "github.com/tribalwarshelp/api/tribehistory/usecase" villagerepo "github.com/tribalwarshelp/api/village/repository" @@ -73,10 +75,11 @@ func main() { Addr: os.Getenv("REDIS_HOST") + ":" + os.Getenv("REDIS_PORT"), Password: os.Getenv("REDIS_PASSWORD"), }) - ctx, _ := context.WithTimeout(context.Background(), time.Second*5) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) if err := redisClient.Ping(ctx).Err(); err != nil { log.Fatal(errors.Wrap(err, "cannot connect to redis")) } + cancel() defer func() { if err := redisClient.Close(); err != nil { log.Fatal(err) @@ -98,6 +101,7 @@ func main() { tribehistoryRepo := tribehistoryrepo.NewPGRepository(db) playerhistoryRepo := playerhistoryrepo.NewPGRepository(db) serverstatsRepo := serverstatsrepo.NewPGRepository(db) + tribeChangeRepo := tribechangerepo.NewPGRepository(db) liveennoblementRepo := liveennoblementrepo.NewPGRepository(db, redisClient) serverUcase := serverucase.New(serverRepo) @@ -129,6 +133,7 @@ func main() { TribeHistoryUcase: tribehistoryucase.New(tribehistoryRepo), PlayerHistoryUcase: playerhistoryucase.New(playerhistoryRepo), ServerStatsUcase: serverstatsucase.New(serverstatsRepo), + TribeChangeUcase: tribechangeucase.New(tribeChangeRepo), }, }) @@ -149,7 +154,7 @@ func main() { <-quit log.Println("Shutdown Server ...") - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { log.Fatal("Server Shutdown:", err) diff --git a/tribechange/constants.go b/tribechange/constants.go new file mode 100644 index 0000000..2d1683a --- /dev/null +++ b/tribechange/constants.go @@ -0,0 +1,5 @@ +package tribechange + +const ( + PaginationLimit = 100 +) diff --git a/tribechange/repository.go b/tribechange/repository.go new file mode 100644 index 0000000..6c024d0 --- /dev/null +++ b/tribechange/repository.go @@ -0,0 +1,17 @@ +package tribechange + +import ( + "context" + + "github.com/tribalwarshelp/shared/models" +) + +type FetchConfig struct { + Server string + Filter *models.TribeChangeFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.TribeChange, int, error) +} diff --git a/tribechange/repository/pg_repository.go b/tribechange/repository/pg_repository.go new file mode 100644 index 0000000..48d2fe9 --- /dev/null +++ b/tribechange/repository/pg_repository.go @@ -0,0 +1,52 @@ +package repository + +import ( + "context" + "fmt" + "strings" + + "github.com/go-pg/pg/v10" + "github.com/pkg/errors" + "github.com/tribalwarshelp/api/tribechange" + "github.com/tribalwarshelp/shared/models" +) + +type pgRepository struct { + *pg.DB +} + +func NewPGRepository(db *pg.DB) tribechange.Repository { + return &pgRepository{db} +} + +func (repo *pgRepository) Fetch(ctx context.Context, cfg tribechange.FetchConfig) ([]*models.TribeChange, int, error) { + var err error + total := 0 + data := []*models.TribeChange{} + query := repo.WithParam("SERVER", pg.Safe(cfg.Server)).Model(&data).Context(ctx) + + if cfg.Filter != nil { + query = query. + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) + + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) + } + } + + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } + if err != nil && err != pg.ErrNoRows { + if strings.Contains(err.Error(), `relation "`+cfg.Server) { + return nil, 0, fmt.Errorf("Server not found") + } + return nil, 0, errors.Wrap(err, "Internal server error") + } + + return data, total, nil +} diff --git a/tribechange/usecase.go b/tribechange/usecase.go new file mode 100644 index 0000000..f1f4d79 --- /dev/null +++ b/tribechange/usecase.go @@ -0,0 +1,11 @@ +package tribechange + +import ( + "context" + + "github.com/tribalwarshelp/shared/models" +) + +type Usecase interface { + Fetch(ctx context.Context, server string, filter *models.TribeChangeFilter) ([]*models.TribeChange, int, error) +} diff --git a/tribechange/usecase/tribechange_usecase.go b/tribechange/usecase/tribechange_usecase.go new file mode 100644 index 0000000..276e4fc --- /dev/null +++ b/tribechange/usecase/tribechange_usecase.go @@ -0,0 +1,32 @@ +package usecase + +import ( + "context" + + "github.com/tribalwarshelp/api/tribechange" + "github.com/tribalwarshelp/api/utils" + "github.com/tribalwarshelp/shared/models" +) + +type usecase struct { + repo tribechange.Repository +} + +func New(repo tribechange.Repository) tribechange.Usecase { + return &usecase{repo} +} + +func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.TribeChangeFilter) ([]*models.TribeChange, int, error) { + if filter == nil { + filter = &models.TribeChangeFilter{} + } + if filter.Limit > tribechange.PaginationLimit || filter.Limit <= 0 { + filter.Limit = tribechange.PaginationLimit + } + filter.Sort = utils.SanitizeSort(filter.Sort) + return ucase.repo.Fetch(ctx, tribechange.FetchConfig{ + Server: server, + Filter: filter, + Count: true, + }) +} From df771d0503c064fa4f1f81b61c6d203fca66633a Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Wed, 24 Jun 2020 16:40:29 +0200 Subject: [PATCH 3/5] 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 --- go.mod | 2 +- go.sum | 3 + .../dataloaders/lang_version_data_loaders.go | 18 +- .../playernamechangesloader_gen.go | 225 +++++++++ graphql/generated/generated.go | 459 +++++++++++++++++- graphql/gqlgen.yml | 2 + graphql/resolvers/player.go | 14 + graphql/schema/player.graphql | 14 + graphql/schema/tribe.graphql | 9 +- player/repository.go | 1 + player/repository/pg_repository.go | 17 + 11 files changed, 753 insertions(+), 11 deletions(-) create mode 100644 graphql/dataloaders/playernamechangesloader_gen.go diff --git a/go.mod b/go.mod index 1fab6ca..7931866 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 737b4e1..42cc251 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/graphql/dataloaders/lang_version_data_loaders.go b/graphql/dataloaders/lang_version_data_loaders.go index 6550e80..b34ec0f 100644 --- a/graphql/dataloaders/lang_version_data_loaders.go +++ b/graphql/dataloaders/lang_version_data_loaders.go @@ -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 + }, + }, } } diff --git a/graphql/dataloaders/playernamechangesloader_gen.go b/graphql/dataloaders/playernamechangesloader_gen.go new file mode 100644 index 0000000..9ae96d3 --- /dev/null +++ b/graphql/dataloaders/playernamechangesloader_gen.go @@ -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) +} diff --git a/graphql/generated/generated.go b/graphql/generated/generated.go index 0df3d7e..703800d 100644 --- a/graphql/generated/generated.go +++ b/graphql/generated/generated.go @@ -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) } diff --git a/graphql/gqlgen.yml b/graphql/gqlgen.yml index 1f5b18d..54fd761 100644 --- a/graphql/gqlgen.yml +++ b/graphql/gqlgen.yml @@ -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 diff --git a/graphql/resolvers/player.go b/graphql/resolvers/player.go index 6b2bbe7..d27b84f 100644 --- a/graphql/resolvers/player.go +++ b/graphql/resolvers/player.go @@ -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{} diff --git a/graphql/schema/player.graphql b/graphql/schema/player.graphql index 5c5a4fe..c630012 100644 --- a/graphql/schema/player.graphql +++ b/graphql/schema/player.graphql @@ -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 diff --git a/graphql/schema/tribe.graphql b/graphql/schema/tribe.graphql index ac5e8c9..bf6da4e 100644 --- a/graphql/schema/tribe.graphql +++ b/graphql/schema/tribe.graphql @@ -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 diff --git a/player/repository.go b/player/repository.go index 061a9bd..5f91a94 100644 --- a/player/repository.go +++ b/player/repository.go @@ -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) } diff --git a/player/repository/pg_repository.go b/player/repository/pg_repository.go index ec9fa15..51c6fac 100644 --- a/player/repository/pg_repository.go +++ b/player/repository/pg_repository.go @@ -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{}). From 96517c910832e4be2f1d0e7726f73561fed4770a Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Thu, 25 Jun 2020 15:12:43 +0200 Subject: [PATCH 4/5] add new fields to Tribe/Player graphql types, bump github.com/tribalwarshelp/shared --- go.mod | 2 +- go.sum | 4 + graphql/generated/generated.go | 706 ++++++++++++++++++++++++++--- graphql/schema/player.graphql | 10 +- graphql/schema/tribe.graphql | 12 +- player/repository/pg_repository.go | 4 +- tribe/repository/pg_repository.go | 4 +- 7 files changed, 664 insertions(+), 78 deletions(-) diff --git a/go.mod b/go.mod index 7931866..d1122ba 100644 --- a/go.mod +++ b/go.mod @@ -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-20200624134544-636239c5fd17 + github.com/tribalwarshelp/shared v0.0.0-20200625131045-74c5a9b3b4f0 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 diff --git a/go.sum b/go.sum index 42cc251..d5b20ab 100644 --- a/go.sum +++ b/go.sum @@ -181,6 +181,10 @@ github.com/tribalwarshelp/shared v0.0.0-20200624131453-e04f1de1bf5c h1:sPu2tYRqZ 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/tribalwarshelp/shared v0.0.0-20200625120510-6d18ee334662 h1:GBCpdHQsOrbz7xz+bTsZlFQJzKi1wsxgAeVFsNIZiH4= +github.com/tribalwarshelp/shared v0.0.0-20200625120510-6d18ee334662/go.mod h1:tf+2yTHasV6jAF3V2deZ9slNoCyBzC0fMdTjI7clf6Y= +github.com/tribalwarshelp/shared v0.0.0-20200625131045-74c5a9b3b4f0 h1:k1j0Nh2OIr1fTrCrbznjPAH+eRVpB3HYXM1sHErrayg= +github.com/tribalwarshelp/shared v0.0.0-20200625131045-74c5a9b3b4f0/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= diff --git a/graphql/generated/generated.go b/graphql/generated/generated.go index 703800d..985ddc9 100644 --- a/graphql/generated/generated.go +++ b/graphql/generated/generated.go @@ -120,26 +120,32 @@ 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 - RankDef func(childComplexity int) int - RankSup func(childComplexity int) int - RankTotal func(childComplexity int) int - ScoreAtt func(childComplexity int) int - ScoreDef func(childComplexity int) int - ScoreSup func(childComplexity int) int - ScoreTotal func(childComplexity int) int - Servers func(childComplexity int) int - TotalVillages func(childComplexity int) int - Tribe func(childComplexity int) int + BestRank func(childComplexity int) int + BestRankAt func(childComplexity int) int + DailyGrowth func(childComplexity int) int + DeletedAt func(childComplexity int) int + Exists func(childComplexity int) int + ID func(childComplexity int) int + JoinedAt func(childComplexity int) int + MostPoints func(childComplexity int) int + MostPointsAt func(childComplexity int) int + MostVillages func(childComplexity int) int + MostVillagesAt 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 + RankDef func(childComplexity int) int + RankSup func(childComplexity int) int + RankTotal func(childComplexity int) int + ScoreAtt func(childComplexity int) int + ScoreDef func(childComplexity int) int + ScoreSup func(childComplexity int) int + ScoreTotal func(childComplexity int) int + Servers func(childComplexity int) int + TotalVillages func(childComplexity int) int + Tribe func(childComplexity int) int } PlayerHistory struct { @@ -384,24 +390,30 @@ 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 - Name func(childComplexity int) int - Points func(childComplexity int) int - Rank func(childComplexity int) int - RankAtt func(childComplexity int) int - RankDef func(childComplexity int) int - RankTotal func(childComplexity int) int - ScoreAtt func(childComplexity int) int - ScoreDef func(childComplexity int) int - ScoreTotal func(childComplexity int) int - Tag func(childComplexity int) int - TotalMembers func(childComplexity int) int - TotalVillages func(childComplexity int) int + AllPoints func(childComplexity int) int + BestRank func(childComplexity int) int + BestRankAt func(childComplexity int) int + CreatedAt func(childComplexity int) int + DeletedAt func(childComplexity int) int + Dominance func(childComplexity int) int + Exists func(childComplexity int) int + ID func(childComplexity int) int + MostPoints func(childComplexity int) int + MostPointsAt func(childComplexity int) int + MostVillages func(childComplexity int) int + MostVillagesAt func(childComplexity int) int + Name func(childComplexity int) int + Points func(childComplexity int) int + Rank func(childComplexity int) int + RankAtt func(childComplexity int) int + RankDef func(childComplexity int) int + RankTotal func(childComplexity int) int + ScoreAtt func(childComplexity int) int + ScoreDef func(childComplexity int) int + ScoreTotal func(childComplexity int) int + Tag func(childComplexity int) int + TotalMembers func(childComplexity int) int + TotalVillages func(childComplexity int) int } TribeChangeRecord struct { @@ -885,6 +897,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.LiveEnnoblement.Village(childComplexity), true + case "Player.bestRank": + if e.complexity.Player.BestRank == nil { + break + } + + return e.complexity.Player.BestRank(childComplexity), true + + case "Player.bestRankAt": + if e.complexity.Player.BestRankAt == nil { + break + } + + return e.complexity.Player.BestRankAt(childComplexity), true + case "Player.dailyGrowth": if e.complexity.Player.DailyGrowth == nil { break @@ -899,12 +925,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Player.DeletedAt(childComplexity), true - case "Player.exist": - if e.complexity.Player.Exist == nil { + case "Player.exists": + if e.complexity.Player.Exists == nil { break } - return e.complexity.Player.Exist(childComplexity), true + return e.complexity.Player.Exists(childComplexity), true case "Player.id": if e.complexity.Player.ID == nil { @@ -920,6 +946,34 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Player.JoinedAt(childComplexity), true + case "Player.mostPoints": + if e.complexity.Player.MostPoints == nil { + break + } + + return e.complexity.Player.MostPoints(childComplexity), true + + case "Player.mostPointsAt": + if e.complexity.Player.MostPointsAt == nil { + break + } + + return e.complexity.Player.MostPointsAt(childComplexity), true + + case "Player.mostVillages": + if e.complexity.Player.MostVillages == nil { + break + } + + return e.complexity.Player.MostVillages(childComplexity), true + + case "Player.mostVillagesAt": + if e.complexity.Player.MostVillagesAt == nil { + break + } + + return e.complexity.Player.MostVillagesAt(childComplexity), true + case "Player.name": if e.complexity.Player.Name == nil { break @@ -2316,6 +2370,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Tribe.AllPoints(childComplexity), true + case "Tribe.bestRank": + if e.complexity.Tribe.BestRank == nil { + break + } + + return e.complexity.Tribe.BestRank(childComplexity), true + + case "Tribe.bestRankAt": + if e.complexity.Tribe.BestRankAt == nil { + break + } + + return e.complexity.Tribe.BestRankAt(childComplexity), true + case "Tribe.createdAt": if e.complexity.Tribe.CreatedAt == nil { break @@ -2337,12 +2405,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Tribe.Dominance(childComplexity), true - case "Tribe.exist": - if e.complexity.Tribe.Exist == nil { + case "Tribe.exists": + if e.complexity.Tribe.Exists == nil { break } - return e.complexity.Tribe.Exist(childComplexity), true + return e.complexity.Tribe.Exists(childComplexity), true case "Tribe.id": if e.complexity.Tribe.ID == nil { @@ -2351,6 +2419,34 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Tribe.ID(childComplexity), true + case "Tribe.mostPoints": + if e.complexity.Tribe.MostPoints == nil { + break + } + + return e.complexity.Tribe.MostPoints(childComplexity), true + + case "Tribe.mostPointsAt": + if e.complexity.Tribe.MostPointsAt == nil { + break + } + + return e.complexity.Tribe.MostPointsAt(childComplexity), true + + case "Tribe.mostVillages": + if e.complexity.Tribe.MostVillages == nil { + break + } + + return e.complexity.Tribe.MostVillages(childComplexity), true + + case "Tribe.mostVillagesAt": + if e.complexity.Tribe.MostVillagesAt == nil { + break + } + + return e.complexity.Tribe.MostVillagesAt(childComplexity), true + case "Tribe.name": if e.complexity.Tribe.Name == nil { break @@ -3006,7 +3102,7 @@ type Player { totalVillages: Int! points: Int! rank: Int! - exist: Boolean! + exists: Boolean! rankAtt: Int! scoreAtt: Int! rankDef: Int! @@ -3016,6 +3112,12 @@ type Player { rankTotal: Int! scoreTotal: Int! dailyGrowth: Int! + bestRank: Int! + bestRankAt: Time! + mostPoints: Int! + mostPointsAt: Time! + mostVillages: Int! + mostVillagesAt: Time! joinedAt: Time! deletedAt: Time tribe: Tribe @goField(forceResolver: true) @@ -3032,7 +3134,7 @@ input PlayerFilter { id: [Int!] idNEQ: [Int!] - exist: Boolean + exists: Boolean name: [String!] nameNEQ: [String!] @@ -3423,7 +3525,7 @@ extend type Query { points: Int! allPoints: Int! rank: Int! - exist: Boolean! + exists: Boolean! rankAtt: Int! scoreAtt: Int! rankDef: Int! @@ -3431,8 +3533,14 @@ extend type Query { rankTotal: Int! scoreTotal: Int! dominance: Float! + bestRank: Int! + bestRankAt: Time! + mostPoints: Int! + mostPointsAt: Time! + mostVillages: Int! + mostVillagesAt: Time! createdAt: Time! - deletedAt: Time! + deletedAt: Time } type TribesList { @@ -3444,7 +3552,7 @@ input TribeFilter { id: [Int!] idNEQ: [Int!] - exist: Boolean + exists: Boolean tag: [String!] tagNEQ: [String!] @@ -5820,7 +5928,7 @@ func (ec *executionContext) _Player_rank(ctx context.Context, field graphql.Coll return ec.marshalNInt2int(ctx, field.Selections, res) } -func (ec *executionContext) _Player_exist(ctx context.Context, field graphql.CollectedField, obj *models.Player) (ret graphql.Marshaler) { +func (ec *executionContext) _Player_exists(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)) @@ -5837,7 +5945,7 @@ func (ec *executionContext) _Player_exist(ctx context.Context, field graphql.Col 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.Exist, nil + return obj.Exists, nil }) if err != nil { ec.Error(ctx, err) @@ -6160,6 +6268,210 @@ func (ec *executionContext) _Player_dailyGrowth(ctx context.Context, field graph return ec.marshalNInt2int(ctx, field.Selections, res) } +func (ec *executionContext) _Player_bestRank(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.BestRank, 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) _Player_bestRankAt(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.BestRankAt, 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) _Player_mostPoints(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.MostPoints, 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) _Player_mostPointsAt(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.MostPointsAt, 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) _Player_mostVillages(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.MostVillages, 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) _Player_mostVillagesAt(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.MostVillagesAt, 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) _Player_joinedAt(ctx context.Context, field graphql.CollectedField, obj *models.Player) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -12586,7 +12898,7 @@ func (ec *executionContext) _Tribe_rank(ctx context.Context, field graphql.Colle return ec.marshalNInt2int(ctx, field.Selections, res) } -func (ec *executionContext) _Tribe_exist(ctx context.Context, field graphql.CollectedField, obj *models.Tribe) (ret graphql.Marshaler) { +func (ec *executionContext) _Tribe_exists(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)) @@ -12603,7 +12915,7 @@ func (ec *executionContext) _Tribe_exist(ctx context.Context, field graphql.Coll 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.Exist, nil + return obj.Exists, nil }) if err != nil { ec.Error(ctx, err) @@ -12858,6 +13170,210 @@ func (ec *executionContext) _Tribe_dominance(ctx context.Context, field graphql. return ec.marshalNFloat2float64(ctx, field.Selections, res) } +func (ec *executionContext) _Tribe_bestRank(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.BestRank, 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_bestRankAt(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.BestRankAt, 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) _Tribe_mostPoints(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.MostPoints, 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_mostPointsAt(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.MostPointsAt, 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) _Tribe_mostVillages(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.MostVillages, 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_mostVillagesAt(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.MostVillagesAt, 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) _Tribe_createdAt(ctx context.Context, field graphql.CollectedField, obj *models.Tribe) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -12916,14 +13432,11 @@ func (ec *executionContext) _Tribe_deletedAt(ctx context.Context, field graphql. 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) + return ec.marshalOTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) _TribeChangeRecord_player(ctx context.Context, field graphql.CollectedField, obj *models.TribeChange) (ret graphql.Marshaler) { @@ -15994,9 +16507,9 @@ func (ec *executionContext) unmarshalInputPlayerFilter(ctx context.Context, obj if err != nil { return it, err } - case "exist": + case "exists": var err error - it.Exist, err = ec.unmarshalOBoolean2ᚖbool(ctx, v) + it.Exists, err = ec.unmarshalOBoolean2ᚖbool(ctx, v) if err != nil { return it, err } @@ -16804,9 +17317,9 @@ func (ec *executionContext) unmarshalInputTribeFilter(ctx context.Context, obj i if err != nil { return it, err } - case "exist": + case "exists": var err error - it.Exist, err = ec.unmarshalOBoolean2ᚖbool(ctx, v) + it.Exists, err = ec.unmarshalOBoolean2ᚖbool(ctx, v) if err != nil { return it, err } @@ -18035,8 +18548,8 @@ func (ec *executionContext) _Player(ctx context.Context, sel ast.SelectionSet, o if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } - case "exist": - out.Values[i] = ec._Player_exist(ctx, field, obj) + case "exists": + out.Values[i] = ec._Player_exists(ctx, field, obj) if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -18085,6 +18598,36 @@ func (ec *executionContext) _Player(ctx context.Context, sel ast.SelectionSet, o if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } + case "bestRank": + out.Values[i] = ec._Player_bestRank(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "bestRankAt": + out.Values[i] = ec._Player_bestRankAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "mostPoints": + out.Values[i] = ec._Player_mostPoints(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "mostPointsAt": + out.Values[i] = ec._Player_mostPointsAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "mostVillages": + out.Values[i] = ec._Player_mostVillages(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "mostVillagesAt": + out.Values[i] = ec._Player_mostVillagesAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } case "joinedAt": out.Values[i] = ec._Player_joinedAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -19699,8 +20242,8 @@ func (ec *executionContext) _Tribe(ctx context.Context, sel ast.SelectionSet, ob if out.Values[i] == graphql.Null { invalids++ } - case "exist": - out.Values[i] = ec._Tribe_exist(ctx, field, obj) + case "exists": + out.Values[i] = ec._Tribe_exists(ctx, field, obj) if out.Values[i] == graphql.Null { invalids++ } @@ -19739,6 +20282,36 @@ func (ec *executionContext) _Tribe(ctx context.Context, sel ast.SelectionSet, ob if out.Values[i] == graphql.Null { invalids++ } + case "bestRank": + out.Values[i] = ec._Tribe_bestRank(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "bestRankAt": + out.Values[i] = ec._Tribe_bestRankAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "mostPoints": + out.Values[i] = ec._Tribe_mostPoints(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "mostPointsAt": + out.Values[i] = ec._Tribe_mostPointsAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "mostVillages": + out.Values[i] = ec._Tribe_mostVillages(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "mostVillagesAt": + out.Values[i] = ec._Tribe_mostVillagesAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } case "createdAt": out.Values[i] = ec._Tribe_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -19746,9 +20319,6 @@ func (ec *executionContext) _Tribe(ctx context.Context, sel ast.SelectionSet, ob } case "deletedAt": out.Values[i] = ec._Tribe_deletedAt(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ - } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/graphql/schema/player.graphql b/graphql/schema/player.graphql index c630012..ca4a315 100644 --- a/graphql/schema/player.graphql +++ b/graphql/schema/player.graphql @@ -10,7 +10,7 @@ type Player { totalVillages: Int! points: Int! rank: Int! - exist: Boolean! + exists: Boolean! rankAtt: Int! scoreAtt: Int! rankDef: Int! @@ -20,6 +20,12 @@ type Player { rankTotal: Int! scoreTotal: Int! dailyGrowth: Int! + bestRank: Int! + bestRankAt: Time! + mostPoints: Int! + mostPointsAt: Time! + mostVillages: Int! + mostVillagesAt: Time! joinedAt: Time! deletedAt: Time tribe: Tribe @goField(forceResolver: true) @@ -36,7 +42,7 @@ input PlayerFilter { id: [Int!] idNEQ: [Int!] - exist: Boolean + exists: Boolean name: [String!] nameNEQ: [String!] diff --git a/graphql/schema/tribe.graphql b/graphql/schema/tribe.graphql index bf6da4e..418b4b8 100644 --- a/graphql/schema/tribe.graphql +++ b/graphql/schema/tribe.graphql @@ -7,7 +7,7 @@ type Tribe { points: Int! allPoints: Int! rank: Int! - exist: Boolean! + exists: Boolean! rankAtt: Int! scoreAtt: Int! rankDef: Int! @@ -15,8 +15,14 @@ type Tribe { rankTotal: Int! scoreTotal: Int! dominance: Float! + bestRank: Int! + bestRankAt: Time! + mostPoints: Int! + mostPointsAt: Time! + mostVillages: Int! + mostVillagesAt: Time! createdAt: Time! - deletedAt: Time! + deletedAt: Time } type TribesList { @@ -28,7 +34,7 @@ input TribeFilter { id: [Int!] idNEQ: [Int!] - exist: Boolean + exists: Boolean tag: [String!] tagNEQ: [String!] diff --git a/player/repository/pg_repository.go b/player/repository/pg_repository.go index 51c6fac..da8e41e 100644 --- a/player/repository/pg_repository.go +++ b/player/repository/pg_repository.go @@ -35,8 +35,8 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg player.FetchConfig) ([] query = query.Order(cfg.Filter.Sort) } - if cfg.Filter.Exist != nil { - query = query.Where("exist = ?", *cfg.Filter.Exist) + if cfg.Filter.Exists != nil { + query = query.Where("exists = ?", *cfg.Filter.Exists) } if cfg.Filter.TribeFilter != nil { diff --git a/tribe/repository/pg_repository.go b/tribe/repository/pg_repository.go index 1c50030..3382701 100644 --- a/tribe/repository/pg_repository.go +++ b/tribe/repository/pg_repository.go @@ -35,8 +35,8 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg tribe.FetchConfig) ([]* query = query.Order(cfg.Filter.Sort) } - if cfg.Filter.Exist != nil { - query = query.Where("exist = ?", *cfg.Filter.Exist) + if cfg.Filter.Exists != nil { + query = query.Where("exist = ?", *cfg.Filter.Exists) } } From c19c510b24d0ef5f6742b7cf5013668d0cc6777c Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Thu, 25 Jun 2020 16:02:00 +0200 Subject: [PATCH 5/5] add dailyplayerstats/dailytribestats resolvers/usecases/repositories --- dailyplayerstats/constants.go | 5 + dailyplayerstats/repository.go | 17 + dailyplayerstats/repository/pg_repository.go | 52 + dailyplayerstats/usecase.go | 11 + .../usecase/dailyplayerstats_usecase.go | 32 + dailytribestats/constants.go | 5 + dailytribestats/repository.go | 17 + dailytribestats/repository/pg_repository.go | 52 + dailytribestats/usecase.go | 11 + .../usecase/dailytribestats_usecase.go | 32 + graphql/generated/generated.go | 2132 +++++++++++++++++ graphql/generated/models.go | 10 + graphql/gqlgen.yml | 8 + graphql/resolvers/daily_player_stats.go | 23 + graphql/resolvers/daily_tribe_stats.go | 23 + graphql/resolvers/resolver.go | 34 +- graphql/schema/daily_player_stats.graphql | 42 + graphql/schema/daily_tribe_stats.graphql | 43 + main.go | 30 +- 19 files changed, 2557 insertions(+), 22 deletions(-) create mode 100644 dailyplayerstats/constants.go create mode 100644 dailyplayerstats/repository.go create mode 100644 dailyplayerstats/repository/pg_repository.go create mode 100644 dailyplayerstats/usecase.go create mode 100644 dailyplayerstats/usecase/dailyplayerstats_usecase.go create mode 100644 dailytribestats/constants.go create mode 100644 dailytribestats/repository.go create mode 100644 dailytribestats/repository/pg_repository.go create mode 100644 dailytribestats/usecase.go create mode 100644 dailytribestats/usecase/dailytribestats_usecase.go create mode 100644 graphql/resolvers/daily_player_stats.go create mode 100644 graphql/resolvers/daily_tribe_stats.go create mode 100644 graphql/schema/daily_player_stats.graphql create mode 100644 graphql/schema/daily_tribe_stats.graphql diff --git a/dailyplayerstats/constants.go b/dailyplayerstats/constants.go new file mode 100644 index 0000000..85a2425 --- /dev/null +++ b/dailyplayerstats/constants.go @@ -0,0 +1,5 @@ +package dailyplayerstats + +const ( + PaginationLimit = 500 +) diff --git a/dailyplayerstats/repository.go b/dailyplayerstats/repository.go new file mode 100644 index 0000000..2ac5ff7 --- /dev/null +++ b/dailyplayerstats/repository.go @@ -0,0 +1,17 @@ +package dailyplayerstats + +import ( + "context" + + "github.com/tribalwarshelp/shared/models" +) + +type FetchConfig struct { + Server string + Filter *models.DailyPlayerStatsFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.DailyPlayerStats, int, error) +} diff --git a/dailyplayerstats/repository/pg_repository.go b/dailyplayerstats/repository/pg_repository.go new file mode 100644 index 0000000..5001085 --- /dev/null +++ b/dailyplayerstats/repository/pg_repository.go @@ -0,0 +1,52 @@ +package repository + +import ( + "context" + "fmt" + "strings" + + "github.com/go-pg/pg/v10" + "github.com/pkg/errors" + "github.com/tribalwarshelp/api/dailyplayerstats" + "github.com/tribalwarshelp/shared/models" +) + +type pgRepository struct { + *pg.DB +} + +func NewPGRepository(db *pg.DB) dailyplayerstats.Repository { + return &pgRepository{db} +} + +func (repo *pgRepository) Fetch(ctx context.Context, cfg dailyplayerstats.FetchConfig) ([]*models.DailyPlayerStats, int, error) { + var err error + data := []*models.DailyPlayerStats{} + total := 0 + query := repo.WithParam("SERVER", pg.Safe(cfg.Server)).Model(&data).Context(ctx) + + if cfg.Filter != nil { + query = query. + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) + + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) + } + } + + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } + if err != nil && err != pg.ErrNoRows { + if strings.Contains(err.Error(), `relation "`+cfg.Server) { + return nil, 0, fmt.Errorf("Server not found") + } + return nil, 0, errors.Wrap(err, "Internal server error") + } + + return data, total, nil +} diff --git a/dailyplayerstats/usecase.go b/dailyplayerstats/usecase.go new file mode 100644 index 0000000..63782d8 --- /dev/null +++ b/dailyplayerstats/usecase.go @@ -0,0 +1,11 @@ +package dailyplayerstats + +import ( + "context" + + "github.com/tribalwarshelp/shared/models" +) + +type Usecase interface { + Fetch(ctx context.Context, server string, filter *models.DailyPlayerStatsFilter) ([]*models.DailyPlayerStats, int, error) +} diff --git a/dailyplayerstats/usecase/dailyplayerstats_usecase.go b/dailyplayerstats/usecase/dailyplayerstats_usecase.go new file mode 100644 index 0000000..b97c4f2 --- /dev/null +++ b/dailyplayerstats/usecase/dailyplayerstats_usecase.go @@ -0,0 +1,32 @@ +package usecase + +import ( + "context" + + "github.com/tribalwarshelp/api/dailyplayerstats" + "github.com/tribalwarshelp/api/utils" + "github.com/tribalwarshelp/shared/models" +) + +type usecase struct { + repo dailyplayerstats.Repository +} + +func New(repo dailyplayerstats.Repository) dailyplayerstats.Usecase { + return &usecase{repo} +} + +func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.DailyPlayerStatsFilter) ([]*models.DailyPlayerStats, int, error) { + if filter == nil { + filter = &models.DailyPlayerStatsFilter{} + } + if filter.Limit > dailyplayerstats.PaginationLimit || filter.Limit <= 0 { + filter.Limit = dailyplayerstats.PaginationLimit + } + filter.Sort = utils.SanitizeSort(filter.Sort) + return ucase.repo.Fetch(ctx, dailyplayerstats.FetchConfig{ + Server: server, + Filter: filter, + Count: true, + }) +} diff --git a/dailytribestats/constants.go b/dailytribestats/constants.go new file mode 100644 index 0000000..21cf11c --- /dev/null +++ b/dailytribestats/constants.go @@ -0,0 +1,5 @@ +package dailytribestats + +const ( + PaginationLimit = 500 +) diff --git a/dailytribestats/repository.go b/dailytribestats/repository.go new file mode 100644 index 0000000..d67a796 --- /dev/null +++ b/dailytribestats/repository.go @@ -0,0 +1,17 @@ +package dailytribestats + +import ( + "context" + + "github.com/tribalwarshelp/shared/models" +) + +type FetchConfig struct { + Server string + Filter *models.DailyTribeStatsFilter + Count bool +} + +type Repository interface { + Fetch(ctx context.Context, cfg FetchConfig) ([]*models.DailyTribeStats, int, error) +} diff --git a/dailytribestats/repository/pg_repository.go b/dailytribestats/repository/pg_repository.go new file mode 100644 index 0000000..3a909ad --- /dev/null +++ b/dailytribestats/repository/pg_repository.go @@ -0,0 +1,52 @@ +package repository + +import ( + "context" + "fmt" + "strings" + + "github.com/go-pg/pg/v10" + "github.com/pkg/errors" + "github.com/tribalwarshelp/api/dailytribestats" + "github.com/tribalwarshelp/shared/models" +) + +type pgRepository struct { + *pg.DB +} + +func NewPGRepository(db *pg.DB) dailytribestats.Repository { + return &pgRepository{db} +} + +func (repo *pgRepository) Fetch(ctx context.Context, cfg dailytribestats.FetchConfig) ([]*models.DailyTribeStats, int, error) { + var err error + data := []*models.DailyTribeStats{} + total := 0 + query := repo.WithParam("SERVER", pg.Safe(cfg.Server)).Model(&data).Context(ctx) + + if cfg.Filter != nil { + query = query. + WhereStruct(cfg.Filter). + Limit(cfg.Filter.Limit). + Offset(cfg.Filter.Offset) + + if cfg.Filter.Sort != "" { + query = query.Order(cfg.Filter.Sort) + } + } + + if cfg.Count { + total, err = query.SelectAndCount() + } else { + err = query.Select() + } + if err != nil && err != pg.ErrNoRows { + if strings.Contains(err.Error(), `relation "`+cfg.Server) { + return nil, 0, fmt.Errorf("Server not found") + } + return nil, 0, errors.Wrap(err, "Internal server error") + } + + return data, total, nil +} diff --git a/dailytribestats/usecase.go b/dailytribestats/usecase.go new file mode 100644 index 0000000..58a75c5 --- /dev/null +++ b/dailytribestats/usecase.go @@ -0,0 +1,11 @@ +package dailytribestats + +import ( + "context" + + "github.com/tribalwarshelp/shared/models" +) + +type Usecase interface { + Fetch(ctx context.Context, server string, filter *models.DailyTribeStatsFilter) ([]*models.DailyTribeStats, int, error) +} diff --git a/dailytribestats/usecase/dailytribestats_usecase.go b/dailytribestats/usecase/dailytribestats_usecase.go new file mode 100644 index 0000000..072b11e --- /dev/null +++ b/dailytribestats/usecase/dailytribestats_usecase.go @@ -0,0 +1,32 @@ +package usecase + +import ( + "context" + + "github.com/tribalwarshelp/api/dailytribestats" + "github.com/tribalwarshelp/api/utils" + "github.com/tribalwarshelp/shared/models" +) + +type usecase struct { + repo dailytribestats.Repository +} + +func New(repo dailytribestats.Repository) dailytribestats.Usecase { + return &usecase{repo} +} + +func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.DailyTribeStatsFilter) ([]*models.DailyTribeStats, int, error) { + if filter == nil { + filter = &models.DailyTribeStatsFilter{} + } + if filter.Limit > dailytribestats.PaginationLimit || filter.Limit <= 0 { + filter.Limit = dailytribestats.PaginationLimit + } + filter.Sort = utils.SanitizeSort(filter.Sort) + return ucase.repo.Fetch(ctx, dailytribestats.FetchConfig{ + Server: server, + Filter: filter, + Count: true, + }) +} diff --git a/graphql/generated/generated.go b/graphql/generated/generated.go index 985ddc9..8f71bb2 100644 --- a/graphql/generated/generated.go +++ b/graphql/generated/generated.go @@ -36,6 +36,8 @@ type Config struct { } type ResolverRoot interface { + DailyPlayerStatsRecord() DailyPlayerStatsRecordResolver + DailyTribeStatsRecord() DailyTribeStatsRecordResolver Ennoblement() EnnoblementResolver LiveEnnoblement() LiveEnnoblementResolver Player() PlayerResolver @@ -86,6 +88,49 @@ type ComplexityRoot struct { Wood func(childComplexity int) int } + DailyPlayerStats struct { + Items func(childComplexity int) int + Total func(childComplexity int) int + } + + DailyPlayerStatsRecord struct { + CreatedAt func(childComplexity int) int + Player func(childComplexity int) int + Points func(childComplexity int) int + Rank func(childComplexity int) int + RankAtt func(childComplexity int) int + RankDef func(childComplexity int) int + RankSup func(childComplexity int) int + RankTotal func(childComplexity int) int + ScoreAtt func(childComplexity int) int + ScoreDef func(childComplexity int) int + ScoreSup func(childComplexity int) int + ScoreTotal func(childComplexity int) int + Villages func(childComplexity int) int + } + + DailyTribeStats struct { + Items func(childComplexity int) int + Total func(childComplexity int) int + } + + DailyTribeStatsRecord struct { + AllPoints func(childComplexity int) int + CreatedAt func(childComplexity int) int + Dominance func(childComplexity int) int + Members func(childComplexity int) int + Points func(childComplexity int) int + Rank func(childComplexity int) int + RankAtt func(childComplexity int) int + RankDef func(childComplexity int) int + RankTotal func(childComplexity int) int + ScoreAtt func(childComplexity int) int + ScoreDef func(childComplexity int) int + ScoreTotal func(childComplexity int) int + Tribe func(childComplexity int) int + Villages func(childComplexity int) int + } + Ennoblement struct { EnnobledAt func(childComplexity int) int NewOwner func(childComplexity int) int @@ -182,6 +227,8 @@ type ComplexityRoot struct { } Query struct { + DailyPlayerStats func(childComplexity int, server string, filter *models.DailyPlayerStatsFilter) int + DailyTribeStats func(childComplexity int, server string, filter *models.DailyTribeStatsFilter) int Ennoblements func(childComplexity int, server string, filter *models.EnnoblementFilter) int LangVersion func(childComplexity int, tag models.LanguageTag) int LangVersions func(childComplexity int, filter *models.LangVersionFilter) int @@ -498,6 +545,12 @@ type ComplexityRoot struct { } } +type DailyPlayerStatsRecordResolver interface { + Player(ctx context.Context, obj *models.DailyPlayerStats) (*models.Player, error) +} +type DailyTribeStatsRecordResolver interface { + Tribe(ctx context.Context, obj *models.DailyTribeStats) (*models.Tribe, error) +} type EnnoblementResolver interface { Village(ctx context.Context, obj *models.Ennoblement) (*models.Village, error) NewOwner(ctx context.Context, obj *models.Ennoblement) (*models.Player, error) @@ -521,6 +574,8 @@ type PlayerHistoryRecordResolver interface { Tribe(ctx context.Context, obj *models.PlayerHistory) (*models.Tribe, error) } type QueryResolver interface { + DailyPlayerStats(ctx context.Context, server string, filter *models.DailyPlayerStatsFilter) (*DailyPlayerStats, error) + DailyTribeStats(ctx context.Context, server string, filter *models.DailyTribeStatsFilter) (*DailyTribeStats, error) Ennoblements(ctx context.Context, server string, filter *models.EnnoblementFilter) (*EnnoblementsList, error) LangVersions(ctx context.Context, filter *models.LangVersionFilter) (*LangVersionsList, error) LangVersion(ctx context.Context, tag models.LanguageTag) (*models.LangVersion, error) @@ -771,6 +826,223 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.BuildingConfig.Wood(childComplexity), true + case "DailyPlayerStats.items": + if e.complexity.DailyPlayerStats.Items == nil { + break + } + + return e.complexity.DailyPlayerStats.Items(childComplexity), true + + case "DailyPlayerStats.total": + if e.complexity.DailyPlayerStats.Total == nil { + break + } + + return e.complexity.DailyPlayerStats.Total(childComplexity), true + + case "DailyPlayerStatsRecord.createdAt": + if e.complexity.DailyPlayerStatsRecord.CreatedAt == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.CreatedAt(childComplexity), true + + case "DailyPlayerStatsRecord.player": + if e.complexity.DailyPlayerStatsRecord.Player == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.Player(childComplexity), true + + case "DailyPlayerStatsRecord.points": + if e.complexity.DailyPlayerStatsRecord.Points == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.Points(childComplexity), true + + case "DailyPlayerStatsRecord.rank": + if e.complexity.DailyPlayerStatsRecord.Rank == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.Rank(childComplexity), true + + case "DailyPlayerStatsRecord.rankAtt": + if e.complexity.DailyPlayerStatsRecord.RankAtt == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.RankAtt(childComplexity), true + + case "DailyPlayerStatsRecord.rankDef": + if e.complexity.DailyPlayerStatsRecord.RankDef == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.RankDef(childComplexity), true + + case "DailyPlayerStatsRecord.rankSup": + if e.complexity.DailyPlayerStatsRecord.RankSup == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.RankSup(childComplexity), true + + case "DailyPlayerStatsRecord.rankTotal": + if e.complexity.DailyPlayerStatsRecord.RankTotal == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.RankTotal(childComplexity), true + + case "DailyPlayerStatsRecord.scoreAtt": + if e.complexity.DailyPlayerStatsRecord.ScoreAtt == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.ScoreAtt(childComplexity), true + + case "DailyPlayerStatsRecord.scoreDef": + if e.complexity.DailyPlayerStatsRecord.ScoreDef == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.ScoreDef(childComplexity), true + + case "DailyPlayerStatsRecord.scoreSup": + if e.complexity.DailyPlayerStatsRecord.ScoreSup == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.ScoreSup(childComplexity), true + + case "DailyPlayerStatsRecord.scoreTotal": + if e.complexity.DailyPlayerStatsRecord.ScoreTotal == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.ScoreTotal(childComplexity), true + + case "DailyPlayerStatsRecord.villages": + if e.complexity.DailyPlayerStatsRecord.Villages == nil { + break + } + + return e.complexity.DailyPlayerStatsRecord.Villages(childComplexity), true + + case "DailyTribeStats.items": + if e.complexity.DailyTribeStats.Items == nil { + break + } + + return e.complexity.DailyTribeStats.Items(childComplexity), true + + case "DailyTribeStats.total": + if e.complexity.DailyTribeStats.Total == nil { + break + } + + return e.complexity.DailyTribeStats.Total(childComplexity), true + + case "DailyTribeStatsRecord.allPoints": + if e.complexity.DailyTribeStatsRecord.AllPoints == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.AllPoints(childComplexity), true + + case "DailyTribeStatsRecord.createdAt": + if e.complexity.DailyTribeStatsRecord.CreatedAt == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.CreatedAt(childComplexity), true + + case "DailyTribeStatsRecord.dominance": + if e.complexity.DailyTribeStatsRecord.Dominance == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.Dominance(childComplexity), true + + case "DailyTribeStatsRecord.members": + if e.complexity.DailyTribeStatsRecord.Members == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.Members(childComplexity), true + + case "DailyTribeStatsRecord.points": + if e.complexity.DailyTribeStatsRecord.Points == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.Points(childComplexity), true + + case "DailyTribeStatsRecord.rank": + if e.complexity.DailyTribeStatsRecord.Rank == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.Rank(childComplexity), true + + case "DailyTribeStatsRecord.rankAtt": + if e.complexity.DailyTribeStatsRecord.RankAtt == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.RankAtt(childComplexity), true + + case "DailyTribeStatsRecord.rankDef": + if e.complexity.DailyTribeStatsRecord.RankDef == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.RankDef(childComplexity), true + + case "DailyTribeStatsRecord.rankTotal": + if e.complexity.DailyTribeStatsRecord.RankTotal == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.RankTotal(childComplexity), true + + case "DailyTribeStatsRecord.scoreAtt": + if e.complexity.DailyTribeStatsRecord.ScoreAtt == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.ScoreAtt(childComplexity), true + + case "DailyTribeStatsRecord.scoreDef": + if e.complexity.DailyTribeStatsRecord.ScoreDef == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.ScoreDef(childComplexity), true + + case "DailyTribeStatsRecord.scoreTotal": + if e.complexity.DailyTribeStatsRecord.ScoreTotal == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.ScoreTotal(childComplexity), true + + case "DailyTribeStatsRecord.tribe": + if e.complexity.DailyTribeStatsRecord.Tribe == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.Tribe(childComplexity), true + + case "DailyTribeStatsRecord.villages": + if e.complexity.DailyTribeStatsRecord.Villages == nil { + break + } + + return e.complexity.DailyTribeStatsRecord.Villages(childComplexity), true + case "Ennoblement.ennobledAt": if e.complexity.Ennoblement.EnnobledAt == nil { break @@ -1226,6 +1498,30 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.PlayersList.Total(childComplexity), true + case "Query.dailyPlayerStats": + if e.complexity.Query.DailyPlayerStats == nil { + break + } + + args, err := ec.field_Query_dailyPlayerStats_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DailyPlayerStats(childComplexity, args["server"].(string), args["filter"].(*models.DailyPlayerStatsFilter)), true + + case "Query.dailyTribeStats": + if e.complexity.Query.DailyTribeStats == nil { + break + } + + args, err := ec.field_Query_dailyTribeStats_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DailyTribeStats(childComplexity, args["server"].(string), args["filter"].(*models.DailyTribeStatsFilter)), true + case "Query.ennoblements": if e.complexity.Query.Ennoblements == nil { break @@ -2993,6 +3289,93 @@ type BuildingConfig { hide: Building! wall: Building! } +`, BuiltIn: false}, + &ast.Source{Name: "schema/daily_player_stats.graphql", Input: `type DailyPlayerStatsRecord { + player: Player @goField(forceResolver: true) + villages: Int! + points: Int! + rank: Int! + rankAtt: Int! + scoreAtt: Int! + rankDef: Int! + scoreDef: Int! + rankSup: Int! + scoreSup: Int! + rankTotal: Int! + scoreTotal: Int! + createdAt: Time! +} + +type DailyPlayerStats { + total: Int! + items: [DailyPlayerStatsRecord!] +} + +input DailyPlayerStatsFilter { + playerID: [Int!] + playerIDNEQ: [Int!] + + createdAt: Time + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + offset: Int + limit: Int + sort: String +} + +extend type Query { + dailyPlayerStats( + server: String! + filter: DailyPlayerStatsFilter + ): DailyPlayerStats! +} +`, BuiltIn: false}, + &ast.Source{Name: "schema/daily_tribe_stats.graphql", Input: `type DailyTribeStatsRecord { + tribe: Tribe @goField(forceResolver: true) + members: Int! + villages: Int! + points: Int! + allPoints: Int! + rank: Int! + rankAtt: Int! + scoreAtt: Int! + rankDef: Int! + scoreDef: Int! + rankTotal: Int! + scoreTotal: Int! + dominance: Float! + createdAt: Time! +} + +type DailyTribeStats { + total: Int! + items: [DailyTribeStatsRecord!] +} + +input DailyTribeStatsFilter { + tribeID: [Int!] + tribeIDNEQ: [Int!] + + createdAt: Time + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + offset: Int + limit: Int + sort: String +} + +extend type Query { + dailyTribeStats( + server: String! + filter: DailyTribeStatsFilter + ): DailyTribeStats! +} `, BuiltIn: false}, &ast.Source{Name: "schema/directives.graphql", Input: `directive @goField( forceResolver: Boolean @@ -3842,6 +4225,50 @@ func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs return args, nil } +func (ec *executionContext) field_Query_dailyPlayerStats_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["server"]; ok { + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["server"] = arg0 + var arg1 *models.DailyPlayerStatsFilter + if tmp, ok := rawArgs["filter"]; ok { + arg1, err = ec.unmarshalODailyPlayerStatsFilter2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyPlayerStatsFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg1 + return args, nil +} + +func (ec *executionContext) field_Query_dailyTribeStats_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["server"]; ok { + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["server"] = arg0 + var arg1 *models.DailyTribeStatsFilter + if tmp, ok := rawArgs["filter"]; ok { + arg1, err = ec.unmarshalODailyTribeStatsFilter2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyTribeStatsFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg1 + return args, nil +} + func (ec *executionContext) field_Query_ennoblements_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -5176,6 +5603,1048 @@ func (ec *executionContext) _BuildingConfig_wall(ctx context.Context, field grap return ec.marshalNBuilding2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐBuilding(ctx, field.Selections, res) } +func (ec *executionContext) _DailyPlayerStats_total(ctx context.Context, field graphql.CollectedField, obj *DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStats", + 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.Total, 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) _DailyPlayerStats_items(ctx context.Context, field graphql.CollectedField, obj *DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStats", + 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.Items, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*models.DailyPlayerStats) + fc.Result = res + return ec.marshalODailyPlayerStatsRecord2ᚕᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyPlayerStatsᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _DailyPlayerStatsRecord_player(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.DailyPlayerStatsRecord().Player(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*models.Player) + fc.Result = res + return ec.marshalOPlayer2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐPlayer(ctx, field.Selections, res) +} + +func (ec *executionContext) _DailyPlayerStatsRecord_villages(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.Villages, 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) _DailyPlayerStatsRecord_points(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.Points, 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) _DailyPlayerStatsRecord_rank(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.Rank, 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) _DailyPlayerStatsRecord_rankAtt(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.RankAtt, 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) _DailyPlayerStatsRecord_scoreAtt(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.ScoreAtt, 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) _DailyPlayerStatsRecord_rankDef(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.RankDef, 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) _DailyPlayerStatsRecord_scoreDef(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.ScoreDef, 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) _DailyPlayerStatsRecord_rankSup(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.RankSup, 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) _DailyPlayerStatsRecord_scoreSup(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.ScoreSup, 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) _DailyPlayerStatsRecord_rankTotal(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.RankTotal, 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) _DailyPlayerStatsRecord_scoreTotal(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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) _DailyPlayerStatsRecord_createdAt(ctx context.Context, field graphql.CollectedField, obj *models.DailyPlayerStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyPlayerStatsRecord", + 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.CreatedAt, 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) _DailyTribeStats_total(ctx context.Context, field graphql.CollectedField, obj *DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStats", + 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.Total, 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) _DailyTribeStats_items(ctx context.Context, field graphql.CollectedField, obj *DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStats", + 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.Items, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*models.DailyTribeStats) + fc.Result = res + return ec.marshalODailyTribeStatsRecord2ᚕᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyTribeStatsᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _DailyTribeStatsRecord_tribe(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.DailyTribeStatsRecord().Tribe(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*models.Tribe) + fc.Result = res + return ec.marshalOTribe2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐTribe(ctx, field.Selections, res) +} + +func (ec *executionContext) _DailyTribeStatsRecord_members(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.Members, 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) _DailyTribeStatsRecord_villages(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.Villages, 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) _DailyTribeStatsRecord_points(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.Points, 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) _DailyTribeStatsRecord_allPoints(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.AllPoints, 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) _DailyTribeStatsRecord_rank(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.Rank, 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) _DailyTribeStatsRecord_rankAtt(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.RankAtt, 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) _DailyTribeStatsRecord_scoreAtt(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.ScoreAtt, 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) _DailyTribeStatsRecord_rankDef(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.RankDef, 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) _DailyTribeStatsRecord_scoreDef(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.ScoreDef, 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) _DailyTribeStatsRecord_rankTotal(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.RankTotal, 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) _DailyTribeStatsRecord_scoreTotal(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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) _DailyTribeStatsRecord_dominance(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.Dominance, 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.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) _DailyTribeStatsRecord_createdAt(ctx context.Context, field graphql.CollectedField, obj *models.DailyTribeStats) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DailyTribeStatsRecord", + 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.CreatedAt, 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) _Ennoblement_village(ctx context.Context, field graphql.CollectedField, obj *models.Ennoblement) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -7338,6 +8807,88 @@ func (ec *executionContext) _PlayersList_total(ctx context.Context, field graphq return ec.marshalNInt2int(ctx, field.Selections, res) } +func (ec *executionContext) _Query_dailyPlayerStats(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_dailyPlayerStats_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DailyPlayerStats(rctx, args["server"].(string), args["filter"].(*models.DailyPlayerStatsFilter)) + }) + 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.(*DailyPlayerStats) + fc.Result = res + return ec.marshalNDailyPlayerStats2ᚖgithubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐDailyPlayerStats(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_dailyTribeStats(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_dailyTribeStats_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DailyTribeStats(rctx, args["server"].(string), args["filter"].(*models.DailyTribeStatsFilter)) + }) + 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.(*DailyTribeStats) + fc.Result = res + return ec.marshalNDailyTribeStats2ᚖgithubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐDailyTribeStats(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_ennoblements(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -16303,6 +17854,150 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co // region **************************** input.gotpl ***************************** +func (ec *executionContext) unmarshalInputDailyPlayerStatsFilter(ctx context.Context, obj interface{}) (models.DailyPlayerStatsFilter, error) { + var it models.DailyPlayerStatsFilter + var asMap = obj.(map[string]interface{}) + + for k, v := range asMap { + switch k { + case "playerID": + var err error + it.PlayerID, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "playerIDNEQ": + var err error + it.PlayerIdNEQ, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "createdAt": + var err error + it.CreatedAt, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtGT": + var err error + it.CreatedAtGT, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtGTE": + var err error + it.CreatedAtGTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtLT": + var err error + it.CreatedAtLT, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtLTE": + var err error + it.CreatedAtLTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "offset": + var err error + it.Offset, err = ec.unmarshalOInt2int(ctx, v) + if err != nil { + return it, err + } + case "limit": + var err error + it.Limit, err = ec.unmarshalOInt2int(ctx, v) + if err != nil { + return it, err + } + case "sort": + var err error + it.Sort, err = ec.unmarshalOString2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputDailyTribeStatsFilter(ctx context.Context, obj interface{}) (models.DailyTribeStatsFilter, error) { + var it models.DailyTribeStatsFilter + var asMap = obj.(map[string]interface{}) + + for k, v := range asMap { + switch k { + case "tribeID": + var err error + it.TribeID, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "tribeIDNEQ": + var err error + it.TribeIdNEQ, err = ec.unmarshalOInt2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + case "createdAt": + var err error + it.CreatedAt, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtGT": + var err error + it.CreatedAtGT, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtGTE": + var err error + it.CreatedAtGTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtLT": + var err error + it.CreatedAtLT, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "createdAtLTE": + var err error + it.CreatedAtLTE, err = ec.unmarshalOTime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + case "offset": + var err error + it.Offset, err = ec.unmarshalOInt2int(ctx, v) + if err != nil { + return it, err + } + case "limit": + var err error + it.Limit, err = ec.unmarshalOInt2int(ctx, v) + if err != nil { + return it, err + } + case "sort": + var err error + it.Sort, err = ec.unmarshalOString2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputEnnoblementFilter(ctx context.Context, obj interface{}) (models.EnnoblementFilter, error) { var it models.EnnoblementFilter var asMap = obj.(map[string]interface{}) @@ -18270,6 +19965,255 @@ func (ec *executionContext) _BuildingConfig(ctx context.Context, sel ast.Selecti return out } +var dailyPlayerStatsImplementors = []string{"DailyPlayerStats"} + +func (ec *executionContext) _DailyPlayerStats(ctx context.Context, sel ast.SelectionSet, obj *DailyPlayerStats) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, dailyPlayerStatsImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DailyPlayerStats") + case "total": + out.Values[i] = ec._DailyPlayerStats_total(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "items": + out.Values[i] = ec._DailyPlayerStats_items(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var dailyPlayerStatsRecordImplementors = []string{"DailyPlayerStatsRecord"} + +func (ec *executionContext) _DailyPlayerStatsRecord(ctx context.Context, sel ast.SelectionSet, obj *models.DailyPlayerStats) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, dailyPlayerStatsRecordImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DailyPlayerStatsRecord") + case "player": + 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._DailyPlayerStatsRecord_player(ctx, field, obj) + return res + }) + case "villages": + out.Values[i] = ec._DailyPlayerStatsRecord_villages(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "points": + out.Values[i] = ec._DailyPlayerStatsRecord_points(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "rank": + out.Values[i] = ec._DailyPlayerStatsRecord_rank(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "rankAtt": + out.Values[i] = ec._DailyPlayerStatsRecord_rankAtt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "scoreAtt": + out.Values[i] = ec._DailyPlayerStatsRecord_scoreAtt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "rankDef": + out.Values[i] = ec._DailyPlayerStatsRecord_rankDef(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "scoreDef": + out.Values[i] = ec._DailyPlayerStatsRecord_scoreDef(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "rankSup": + out.Values[i] = ec._DailyPlayerStatsRecord_rankSup(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "scoreSup": + out.Values[i] = ec._DailyPlayerStatsRecord_scoreSup(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "rankTotal": + out.Values[i] = ec._DailyPlayerStatsRecord_rankTotal(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "scoreTotal": + out.Values[i] = ec._DailyPlayerStatsRecord_scoreTotal(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "createdAt": + out.Values[i] = ec._DailyPlayerStatsRecord_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var dailyTribeStatsImplementors = []string{"DailyTribeStats"} + +func (ec *executionContext) _DailyTribeStats(ctx context.Context, sel ast.SelectionSet, obj *DailyTribeStats) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, dailyTribeStatsImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DailyTribeStats") + case "total": + out.Values[i] = ec._DailyTribeStats_total(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "items": + out.Values[i] = ec._DailyTribeStats_items(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var dailyTribeStatsRecordImplementors = []string{"DailyTribeStatsRecord"} + +func (ec *executionContext) _DailyTribeStatsRecord(ctx context.Context, sel ast.SelectionSet, obj *models.DailyTribeStats) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, dailyTribeStatsRecordImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DailyTribeStatsRecord") + case "tribe": + 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._DailyTribeStatsRecord_tribe(ctx, field, obj) + return res + }) + case "members": + out.Values[i] = ec._DailyTribeStatsRecord_members(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "villages": + out.Values[i] = ec._DailyTribeStatsRecord_villages(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "points": + out.Values[i] = ec._DailyTribeStatsRecord_points(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "allPoints": + out.Values[i] = ec._DailyTribeStatsRecord_allPoints(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "rank": + out.Values[i] = ec._DailyTribeStatsRecord_rank(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "rankAtt": + out.Values[i] = ec._DailyTribeStatsRecord_rankAtt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "scoreAtt": + out.Values[i] = ec._DailyTribeStatsRecord_scoreAtt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "rankDef": + out.Values[i] = ec._DailyTribeStatsRecord_rankDef(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "scoreDef": + out.Values[i] = ec._DailyTribeStatsRecord_scoreDef(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "rankTotal": + out.Values[i] = ec._DailyTribeStatsRecord_rankTotal(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "scoreTotal": + out.Values[i] = ec._DailyTribeStatsRecord_scoreTotal(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "dominance": + out.Values[i] = ec._DailyTribeStatsRecord_dominance(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "createdAt": + out.Values[i] = ec._DailyTribeStatsRecord_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var ennoblementImplementors = []string{"Ennoblement"} func (ec *executionContext) _Ennoblement(ctx context.Context, sel ast.SelectionSet, obj *models.Ennoblement) graphql.Marshaler { @@ -18899,6 +20843,34 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") + case "dailyPlayerStats": + 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._Query_dailyPlayerStats(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) + case "dailyTribeStats": + 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._Query_dailyTribeStats(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "ennoblements": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -21101,6 +23073,62 @@ func (ec *executionContext) marshalNBuildingConfig2githubᚗcomᚋtribalwarshelp return ec._BuildingConfig(ctx, sel, &v) } +func (ec *executionContext) marshalNDailyPlayerStats2githubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐDailyPlayerStats(ctx context.Context, sel ast.SelectionSet, v DailyPlayerStats) graphql.Marshaler { + return ec._DailyPlayerStats(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDailyPlayerStats2ᚖgithubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐDailyPlayerStats(ctx context.Context, sel ast.SelectionSet, v *DailyPlayerStats) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._DailyPlayerStats(ctx, sel, v) +} + +func (ec *executionContext) marshalNDailyPlayerStatsRecord2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyPlayerStats(ctx context.Context, sel ast.SelectionSet, v models.DailyPlayerStats) graphql.Marshaler { + return ec._DailyPlayerStatsRecord(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDailyPlayerStatsRecord2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyPlayerStats(ctx context.Context, sel ast.SelectionSet, v *models.DailyPlayerStats) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._DailyPlayerStatsRecord(ctx, sel, v) +} + +func (ec *executionContext) marshalNDailyTribeStats2githubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐDailyTribeStats(ctx context.Context, sel ast.SelectionSet, v DailyTribeStats) graphql.Marshaler { + return ec._DailyTribeStats(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDailyTribeStats2ᚖgithubᚗcomᚋtribalwarshelpᚋapiᚋgraphqlᚋgeneratedᚐDailyTribeStats(ctx context.Context, sel ast.SelectionSet, v *DailyTribeStats) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._DailyTribeStats(ctx, sel, v) +} + +func (ec *executionContext) marshalNDailyTribeStatsRecord2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyTribeStats(ctx context.Context, sel ast.SelectionSet, v models.DailyTribeStats) graphql.Marshaler { + return ec._DailyTribeStatsRecord(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDailyTribeStatsRecord2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyTribeStats(ctx context.Context, sel ast.SelectionSet, v *models.DailyTribeStats) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._DailyTribeStatsRecord(ctx, sel, v) +} + func (ec *executionContext) marshalNEnnoblement2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐEnnoblement(ctx context.Context, sel ast.SelectionSet, v models.Ennoblement) graphql.Marshaler { return ec._Ennoblement(ctx, sel, &v) } @@ -21862,6 +23890,110 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast return ec.marshalOBoolean2bool(ctx, sel, *v) } +func (ec *executionContext) unmarshalODailyPlayerStatsFilter2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyPlayerStatsFilter(ctx context.Context, v interface{}) (models.DailyPlayerStatsFilter, error) { + return ec.unmarshalInputDailyPlayerStatsFilter(ctx, v) +} + +func (ec *executionContext) unmarshalODailyPlayerStatsFilter2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyPlayerStatsFilter(ctx context.Context, v interface{}) (*models.DailyPlayerStatsFilter, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalODailyPlayerStatsFilter2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyPlayerStatsFilter(ctx, v) + return &res, err +} + +func (ec *executionContext) marshalODailyPlayerStatsRecord2ᚕᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyPlayerStatsᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.DailyPlayerStats) graphql.Marshaler { + if v == nil { + return graphql.Null + } + 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.marshalNDailyPlayerStatsRecord2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyPlayerStats(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + return ret +} + +func (ec *executionContext) unmarshalODailyTribeStatsFilter2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyTribeStatsFilter(ctx context.Context, v interface{}) (models.DailyTribeStatsFilter, error) { + return ec.unmarshalInputDailyTribeStatsFilter(ctx, v) +} + +func (ec *executionContext) unmarshalODailyTribeStatsFilter2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyTribeStatsFilter(ctx context.Context, v interface{}) (*models.DailyTribeStatsFilter, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalODailyTribeStatsFilter2githubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyTribeStatsFilter(ctx, v) + return &res, err +} + +func (ec *executionContext) marshalODailyTribeStatsRecord2ᚕᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyTribeStatsᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.DailyTribeStats) graphql.Marshaler { + if v == nil { + return graphql.Null + } + 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.marshalNDailyTribeStatsRecord2ᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐDailyTribeStats(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + return ret +} + func (ec *executionContext) marshalOEnnoblement2ᚕᚖgithubᚗcomᚋtribalwarshelpᚋsharedᚋmodelsᚐEnnoblementᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.Ennoblement) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/graphql/generated/models.go b/graphql/generated/models.go index 6dcbfad..399ece9 100644 --- a/graphql/generated/models.go +++ b/graphql/generated/models.go @@ -6,6 +6,16 @@ import ( "github.com/tribalwarshelp/shared/models" ) +type DailyPlayerStats struct { + Total int `json:"total"` + Items []*models.DailyPlayerStats `json:"items"` +} + +type DailyTribeStats struct { + Total int `json:"total"` + Items []*models.DailyTribeStats `json:"items"` +} + type EnnoblementsList struct { Items []*models.Ennoblement `json:"items"` Total int `json:"total"` diff --git a/graphql/gqlgen.yml b/graphql/gqlgen.yml index 54fd761..7d7fd73 100644 --- a/graphql/gqlgen.yml +++ b/graphql/gqlgen.yml @@ -94,5 +94,13 @@ models: model: github.com/tribalwarshelp/shared/models.TribeChange TribeChangeFilter: model: github.com/tribalwarshelp/shared/models.TribeChangeFilter + DailyPlayerStatsRecord: + model: github.com/tribalwarshelp/shared/models.DailyPlayerStats + DailyPlayerStatsFilter: + model: github.com/tribalwarshelp/shared/models.DailyPlayerStatsFilter + DailyTribeStatsRecord: + model: github.com/tribalwarshelp/shared/models.DailyTribeStats + DailyTribeStatsFilter: + model: github.com/tribalwarshelp/shared/models.DailyTribeStatsFilter PlayerNameChange: model: github.com/tribalwarshelp/shared/models.PlayerNameChange diff --git a/graphql/resolvers/daily_player_stats.go b/graphql/resolvers/daily_player_stats.go new file mode 100644 index 0000000..0e36283 --- /dev/null +++ b/graphql/resolvers/daily_player_stats.go @@ -0,0 +1,23 @@ +package resolvers + +import ( + "context" + + "github.com/tribalwarshelp/api/graphql/generated" + "github.com/tribalwarshelp/shared/models" +) + +func (r *dailyPlayerStatsRecordResolver) Player(ctx context.Context, obj *models.DailyPlayerStats) (*models.Player, error) { + if obj.Player != nil { + return obj.Player, nil + } + + return getPlayer(ctx, obj.PlayerID), nil +} + +func (r *queryResolver) DailyPlayerStats(ctx context.Context, server string, filter *models.DailyPlayerStatsFilter) (*generated.DailyPlayerStats, error) { + var err error + list := &generated.DailyPlayerStats{} + list.Items, list.Total, err = r.DailyPlayerStatsUcase.Fetch(ctx, server, filter) + return list, err +} diff --git a/graphql/resolvers/daily_tribe_stats.go b/graphql/resolvers/daily_tribe_stats.go new file mode 100644 index 0000000..de9e26f --- /dev/null +++ b/graphql/resolvers/daily_tribe_stats.go @@ -0,0 +1,23 @@ +package resolvers + +import ( + "context" + + "github.com/tribalwarshelp/api/graphql/generated" + "github.com/tribalwarshelp/shared/models" +) + +func (r *dailyTribeStatsRecordResolver) Tribe(ctx context.Context, obj *models.DailyTribeStats) (*models.Tribe, error) { + if obj.Tribe != nil { + return obj.Tribe, nil + } + + return getTribe(ctx, obj.TribeID), nil +} + +func (r *queryResolver) DailyTribeStats(ctx context.Context, server string, filter *models.DailyTribeStatsFilter) (*generated.DailyTribeStats, error) { + var err error + list := &generated.DailyTribeStats{} + list.Items, list.Total, err = r.DailyTribeStatsUcase.Fetch(ctx, server, filter) + return list, err +} diff --git a/graphql/resolvers/resolver.go b/graphql/resolvers/resolver.go index 2481600..008841a 100644 --- a/graphql/resolvers/resolver.go +++ b/graphql/resolvers/resolver.go @@ -1,6 +1,8 @@ package resolvers import ( + "github.com/tribalwarshelp/api/dailyplayerstats" + "github.com/tribalwarshelp/api/dailytribestats" "github.com/tribalwarshelp/api/ennoblement" "github.com/tribalwarshelp/api/graphql/generated" "github.com/tribalwarshelp/api/langversion" @@ -16,17 +18,19 @@ import ( ) type Resolver struct { - LangVersionUcase langversion.Usecase - ServerUcase server.Usecase - PlayerUcase player.Usecase - TribeUcase tribe.Usecase - VillageUcase village.Usecase - LiveEnnoblementUcase liveennoblement.Usecase - EnnoblementUcase ennoblement.Usecase - PlayerHistoryUcase playerhistory.Usecase - TribeHistoryUcase tribehistory.Usecase - ServerStatsUcase serverstats.Usecase - TribeChangeUcase tribechange.Usecase + LangVersionUcase langversion.Usecase + ServerUcase server.Usecase + PlayerUcase player.Usecase + TribeUcase tribe.Usecase + VillageUcase village.Usecase + LiveEnnoblementUcase liveennoblement.Usecase + EnnoblementUcase ennoblement.Usecase + PlayerHistoryUcase playerhistory.Usecase + TribeHistoryUcase tribehistory.Usecase + ServerStatsUcase serverstats.Usecase + TribeChangeUcase tribechange.Usecase + DailyTribeStatsUcase dailytribestats.Usecase + DailyPlayerStatsUcase dailyplayerstats.Usecase } // Query returns generated.QueryResolver implementation. @@ -47,6 +51,12 @@ func (r *Resolver) TribeHistoryRecord() generated.TribeHistoryRecordResolver { func (r *Resolver) TribeChangeRecord() generated.TribeChangeRecordResolver { return &tribeChangeRecordResolver{r} } +func (r *Resolver) DailyPlayerStatsRecord() generated.DailyPlayerStatsRecordResolver { + return &dailyPlayerStatsRecordResolver{r} +} +func (r *Resolver) DailyTribeStatsRecord() generated.DailyTribeStatsRecordResolver { + return &dailyTribeStatsRecordResolver{r} +} type queryResolver struct{ *Resolver } type playerResolver struct{ *Resolver } @@ -59,3 +69,5 @@ type playerHistoryRecordResolver struct{ *Resolver } type tribeHistoryRecordResolver struct{ *Resolver } type serverStatsRecordResolver struct{ *Resolver } type tribeChangeRecordResolver struct{ *Resolver } +type dailyPlayerStatsRecordResolver struct{ *Resolver } +type dailyTribeStatsRecordResolver struct{ *Resolver } diff --git a/graphql/schema/daily_player_stats.graphql b/graphql/schema/daily_player_stats.graphql new file mode 100644 index 0000000..e75870c --- /dev/null +++ b/graphql/schema/daily_player_stats.graphql @@ -0,0 +1,42 @@ +type DailyPlayerStatsRecord { + player: Player @goField(forceResolver: true) + villages: Int! + points: Int! + rank: Int! + rankAtt: Int! + scoreAtt: Int! + rankDef: Int! + scoreDef: Int! + rankSup: Int! + scoreSup: Int! + rankTotal: Int! + scoreTotal: Int! + createdAt: Time! +} + +type DailyPlayerStats { + total: Int! + items: [DailyPlayerStatsRecord!] +} + +input DailyPlayerStatsFilter { + playerID: [Int!] + playerIDNEQ: [Int!] + + createdAt: Time + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + offset: Int + limit: Int + sort: String +} + +extend type Query { + dailyPlayerStats( + server: String! + filter: DailyPlayerStatsFilter + ): DailyPlayerStats! +} diff --git a/graphql/schema/daily_tribe_stats.graphql b/graphql/schema/daily_tribe_stats.graphql new file mode 100644 index 0000000..783267b --- /dev/null +++ b/graphql/schema/daily_tribe_stats.graphql @@ -0,0 +1,43 @@ +type DailyTribeStatsRecord { + tribe: Tribe @goField(forceResolver: true) + members: Int! + villages: Int! + points: Int! + allPoints: Int! + rank: Int! + rankAtt: Int! + scoreAtt: Int! + rankDef: Int! + scoreDef: Int! + rankTotal: Int! + scoreTotal: Int! + dominance: Float! + createdAt: Time! +} + +type DailyTribeStats { + total: Int! + items: [DailyTribeStatsRecord!] +} + +input DailyTribeStatsFilter { + tribeID: [Int!] + tribeIDNEQ: [Int!] + + createdAt: Time + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + offset: Int + limit: Int + sort: String +} + +extend type Query { + dailyTribeStats( + server: String! + filter: DailyTribeStatsFilter + ): DailyTribeStats! +} diff --git a/main.go b/main.go index 0e0907b..bab224f 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,10 @@ import ( "github.com/tribalwarshelp/api/graphql/dataloaders" + dailyplayerstatsrepo "github.com/tribalwarshelp/api/dailyplayerstats/repository" + dailyplayerstatsucase "github.com/tribalwarshelp/api/dailyplayerstats/usecase" + dailytribestatsrepo "github.com/tribalwarshelp/api/dailytribestats/repository" + 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" @@ -102,6 +106,8 @@ func main() { playerhistoryRepo := playerhistoryrepo.NewPGRepository(db) serverstatsRepo := serverstatsrepo.NewPGRepository(db) tribeChangeRepo := tribechangerepo.NewPGRepository(db) + dailyPlayerStatsRepo := dailyplayerstatsrepo.NewPGRepository(db) + dailyTribeStatsRepo := dailytribestatsrepo.NewPGRepository(db) liveennoblementRepo := liveennoblementrepo.NewPGRepository(db, redisClient) serverUcase := serverucase.New(serverRepo) @@ -123,17 +129,19 @@ func main() { httpdelivery.Attach(httpdelivery.Config{ RouterGroup: graphql, Resolver: &resolvers.Resolver{ - LangVersionUcase: langversionucase.New(langversionRepo), - ServerUcase: serverUcase, - TribeUcase: tribeucase.New(tribeRepo), - PlayerUcase: playerucase.New(playerRepo), - VillageUcase: villageucase.New(villageRepo), - EnnoblementUcase: ennoblementucase.New(ennoblementRepo), - LiveEnnoblementUcase: liveennoblementucase.New(liveennoblementRepo), - TribeHistoryUcase: tribehistoryucase.New(tribehistoryRepo), - PlayerHistoryUcase: playerhistoryucase.New(playerhistoryRepo), - ServerStatsUcase: serverstatsucase.New(serverstatsRepo), - TribeChangeUcase: tribechangeucase.New(tribeChangeRepo), + LangVersionUcase: langversionucase.New(langversionRepo), + ServerUcase: serverUcase, + TribeUcase: tribeucase.New(tribeRepo), + PlayerUcase: playerucase.New(playerRepo), + VillageUcase: villageucase.New(villageRepo), + EnnoblementUcase: ennoblementucase.New(ennoblementRepo), + LiveEnnoblementUcase: liveennoblementucase.New(liveennoblementRepo), + TribeHistoryUcase: tribehistoryucase.New(tribehistoryRepo), + PlayerHistoryUcase: playerhistoryucase.New(playerhistoryRepo), + ServerStatsUcase: serverstatsucase.New(serverstatsRepo), + TribeChangeUcase: tribechangeucase.New(tribeChangeRepo), + DailyPlayerStatsUcase: dailyplayerstatsucase.New(dailyPlayerStatsRepo), + DailyTribeStatsUcase: dailytribestatsucase.New(dailyTribeStatsRepo), }, })