every date which API returns are in UTC timezone, resolver Player.Servers() is returning now servers from one specific game lang version, refactor

This commit is contained in:
Dawid Wysokiński 2020-06-24 15:05:31 +02:00
parent 45826ddea0
commit 87562c3f4c
50 changed files with 460 additions and 488 deletions

View File

@ -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)
}

View File

@ -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")

View File

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

2
go.sum
View File

@ -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=

View File

@ -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
},
},
}
}

View File

@ -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
},
},
}
}

View File

@ -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}

View File

@ -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.marshalNTime2timeᚐ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.marshalNTime2timeᚐ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.marshalNTime2timeᚐ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.marshalNTime2timeᚐ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.marshalNTime2timeᚐ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.marshalNTime2timeᚐ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.marshalNTime2timeᚐ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.marshalNTime2timeᚐ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.marshalNTime2timeᚐ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)
}

View File

@ -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{}

View File

@ -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
}

View File

@ -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{}

View File

@ -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{}

View File

@ -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}
}

View File

@ -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{}

View File

@ -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{}

View File

@ -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{}

View File

@ -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{}

View File

@ -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 {

View File

@ -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)
}

View File

@ -12,7 +12,7 @@ type PlayerHistoryRecord {
rankTotal: Int!
scoreTotal: Int!
tribe: Tribe @goField(forceResolver: true)
createdAt: Time! @goField(forceResolver: true)
createdAt: Time!
}
type PlayerHistory {

View File

@ -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 {

View File

@ -9,7 +9,7 @@ type ServerStatsRecord {
barbarianVillages: Int!
playerVillages: Int!
villages: Int!
createdAt: Time! @goField(forceResolver: true)
createdAt: Time!
}
type ServerStats {

View File

@ -14,7 +14,7 @@ type Tribe {
scoreDef: Int!
rankTotal: Int!
dominance: Float!
createdAt: Time! @goField(forceResolver: true)
createdAt: Time!
scoreTotal: Int!
}

View File

@ -12,7 +12,7 @@ type TribeHistoryRecord {
scoreDef: Int!
rankTotal: Int!
scoreTotal: Int!
createdAt: Time! @goField(forceResolver: true)
createdAt: Time!
}
type TribeHistory {

View File

@ -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)
}

View File

@ -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")
}

View File

@ -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

View File

@ -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")

View File

@ -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 {

View File

@ -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 {

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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 {

View File

@ -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

View File

@ -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)
}

View File

@ -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")

View File

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

View File

@ -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)
}

View File

@ -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")
}

View File

@ -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

View File

@ -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)
}

View File

@ -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")

View File

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

View File

@ -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)
}

View File

@ -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")

View File

@ -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

View File

@ -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)
}

View File

@ -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")

View File

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

View File

@ -1,6 +1,8 @@
package utils
import "time"
import (
"time"
)
func GetLocation(timezone string) *time.Location {
loc, err := time.LoadLocation(timezone)