add ennoblement resolvers, usecase, repository

This commit is contained in:
Dawid Wysokiński 2020-06-21 12:26:57 +02:00
parent 373288e925
commit 52b6f59d94
19 changed files with 1396 additions and 93 deletions

5
ennoblement/constants.go Normal file
View File

@ -0,0 +1,5 @@
package ennoblement
const (
PaginationLimit = 100
)

11
ennoblement/repository.go Normal file
View File

@ -0,0 +1,11 @@
package ennoblement
import (
"context"
"github.com/tribalwarshelp/shared/models"
)
type Repository interface {
Fetch(ctx context.Context, server string, filter *models.EnnoblementFilter) ([]*models.Ennoblement, int, error)
}

View File

@ -0,0 +1,47 @@
package repository
import (
"context"
"fmt"
"strings"
"github.com/go-pg/pg/v10"
"github.com/pkg/errors"
"github.com/tribalwarshelp/api/ennoblement"
"github.com/tribalwarshelp/shared/models"
)
type pgRepository struct {
*pg.DB
}
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) {
var err error
data := []*models.Ennoblement{}
query := repo.WithParam("SERVER", pg.Safe(server)).Model(&data).Context(ctx)
if f != nil {
query = query.
WhereStruct(f).
Limit(f.Limit).
Offset(f.Offset)
if f.Sort != "" {
query = query.Order(f.Sort)
}
}
total, err := query.SelectAndCount()
if err != nil && err != pg.ErrNoRows {
if strings.Contains(err.Error(), `relation "`+server) {
return nil, 0, fmt.Errorf("Server not found")
}
return nil, 0, errors.Wrap(err, "Internal server error")
}
return data, total, nil
}

11
ennoblement/usecase.go Normal file
View File

@ -0,0 +1,11 @@
package ennoblement
import (
"context"
"github.com/tribalwarshelp/shared/models"
)
type Usecase interface {
Fetch(ctx context.Context, server string, filter *models.EnnoblementFilter) ([]*models.Ennoblement, int, error)
}

View File

@ -0,0 +1,28 @@
package usecase
import (
"context"
"github.com/tribalwarshelp/api/ennoblement"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
)
type usecase struct {
repo ennoblement.Repository
}
func New(repo ennoblement.Repository) ennoblement.Usecase {
return &usecase{repo}
}
func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.EnnoblementFilter) ([]*models.Ennoblement, int, error) {
if filter == nil {
filter = &models.EnnoblementFilter{}
}
if filter.Limit > ennoblement.PaginationLimit || filter.Limit <= 0 {
filter.Limit = ennoblement.PaginationLimit
}
filter.Sort = utils.SanitizeSort(filter.Sort)
return ucase.repo.Fetch(ctx, server, filter)
}

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,11 @@ import (
"github.com/tribalwarshelp/shared/models"
)
type EnnoblementsList struct {
Items []*models.Ennoblement `json:"items"`
Total int `json:"total"`
}
type LangVersionsList struct {
Items []*models.LangVersion `json:"items"`
Total int `json:"total"`

View File

@ -74,3 +74,7 @@ models:
model: github.com/tribalwarshelp/shared/models.VillageFilter
LiveEnnoblement:
model: github.com/tribalwarshelp/shared/models.LiveEnnoblement
Ennoblement:
model: github.com/tribalwarshelp/shared/models.Ennoblement
EnnoblementFilter:
model: github.com/tribalwarshelp/shared/models.EnnoblementFilter

View File

@ -0,0 +1,64 @@
package resolvers
import (
"context"
"time"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/shared/models"
)
func (r *ennoblementResolver) NewOwner(ctx context.Context, obj *models.Ennoblement) (*models.Player, error) {
if obj.NewOwner != nil {
return obj.NewOwner, nil
}
return getPlayer(ctx, obj.NewOwnerID), nil
}
func (r *ennoblementResolver) NewOwnerTribe(ctx context.Context, obj *models.Ennoblement) (*models.Tribe, error) {
if obj.NewOwnerTribe != nil {
return obj.NewOwnerTribe, nil
}
return getTribe(ctx, obj.NewOwnerTribeID), nil
}
func (r *ennoblementResolver) OldOwner(ctx context.Context, obj *models.Ennoblement) (*models.Player, error) {
if obj.OldOwner != nil {
return obj.OldOwner, nil
}
return getPlayer(ctx, obj.OldOwnerID), nil
}
func (r *ennoblementResolver) OldOwnerTribe(ctx context.Context, obj *models.Ennoblement) (*models.Tribe, error) {
if obj.OldOwnerTribe != nil {
return obj.OldOwnerTribe, nil
}
return getTribe(ctx, obj.OldOwnerTribeID), nil
}
func (r *ennoblementResolver) Village(ctx context.Context, obj *models.Ennoblement) (*models.Village, error) {
if obj.Village != nil {
return obj.Village, nil
}
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{}
list.Items, list.Total, err = r.EnnoblementUcase.Fetch(ctx, server, f)
return list, err
}

View File

@ -1,8 +1,17 @@
package resolvers
import "github.com/99designs/gqlgen/graphql"
import (
"context"
"time"
func getServer(rctx *graphql.FieldContext) (string, bool) {
"github.com/99designs/gqlgen/graphql"
"github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/shared/models"
)
func getServer(ctx context.Context) (string, bool) {
rctx := graphql.GetFieldContext(ctx)
server := ""
ok := false
for rctx != nil {
@ -14,3 +23,59 @@ func getServer(rctx *graphql.FieldContext) (string, bool) {
}
return server, ok
}
func getPlayer(ctx context.Context, id int) *models.Player {
if server, ok := getServer(ctx); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil {
if dataloader, ok := dataloaders[server]; ok {
player, _ := dataloader.PlayerByID.Load(id)
if player != nil {
return player
}
}
}
}
return nil
}
func getVillage(ctx context.Context, id int) *models.Village {
if server, ok := getServer(ctx); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil {
if dataloader, ok := dataloaders[server]; ok {
player, _ := dataloader.VillageByID.Load(id)
if player != nil {
return player
}
}
}
}
return nil
}
func getTribe(ctx context.Context, id int) *models.Tribe {
if server, ok := getServer(ctx); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil {
if dataloader, ok := dataloaders[server]; ok {
player, _ := dataloader.TribeByID.Load(id)
if player != nil {
return player
}
}
}
}
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

@ -3,8 +3,6 @@ package resolvers
import (
"context"
"github.com/99designs/gqlgen/graphql"
"github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/shared/models"
)
@ -13,19 +11,7 @@ func (r *liveEnnoblementResolver) NewOwner(ctx context.Context, obj *models.Live
return obj.NewOwner, nil
}
if server, ok := getServer(graphql.GetFieldContext(ctx)); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil {
if dataloader, ok := dataloaders[server]; ok {
player, _ := dataloader.PlayerByID.Load(obj.NewOwnerID)
if player != nil {
return player, nil
}
}
}
}
return nil, nil
return getPlayer(ctx, obj.NewOwnerID), nil
}
func (r *liveEnnoblementResolver) OldOwner(ctx context.Context, obj *models.LiveEnnoblement) (*models.Player, error) {
@ -33,19 +19,7 @@ func (r *liveEnnoblementResolver) OldOwner(ctx context.Context, obj *models.Live
return obj.OldOwner, nil
}
if server, ok := getServer(graphql.GetFieldContext(ctx)); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil {
if dataloader, ok := dataloaders[server]; ok {
player, _ := dataloader.PlayerByID.Load(obj.OldOwnerID)
if player != nil {
return player, nil
}
}
}
}
return nil, nil
return getPlayer(ctx, obj.OldOwnerID), nil
}
func (r *liveEnnoblementResolver) Village(ctx context.Context, obj *models.LiveEnnoblement) (*models.Village, error) {
@ -53,19 +27,7 @@ func (r *liveEnnoblementResolver) Village(ctx context.Context, obj *models.LiveE
return obj.Village, nil
}
if server, ok := getServer(graphql.GetFieldContext(ctx)); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil {
if dataloader, ok := dataloaders[server]; ok {
village, _ := dataloader.VillageByID.Load(obj.VillageID)
if village != nil {
return village, nil
}
}
}
}
return nil, nil
return getVillage(ctx, obj.VillageID), nil
}
func (r *queryResolver) LiveEnnoblements(ctx context.Context, server string) ([]*models.LiveEnnoblement, error) {

View File

@ -3,9 +3,7 @@ package resolvers
import (
"context"
"github.com/99designs/gqlgen/graphql"
"github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/shared/models"
)
@ -14,19 +12,7 @@ func (r *playerResolver) Tribe(ctx context.Context, obj *models.Player) (*models
return obj.Tribe, nil
}
if server, ok := getServer(graphql.GetFieldContext(ctx)); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil {
if dataloader, ok := dataloaders[server]; ok {
tribe, _ := dataloader.TribeByID.Load(obj.TribeID)
if tribe != nil {
return tribe, nil
}
}
}
}
return nil, nil
return getTribe(ctx, obj.TribeID), nil
}
func (r *queryResolver) Players(ctx context.Context, server string, filter *models.PlayerFilter) (*generated.PlayersList, error) {

View File

@ -1,6 +1,7 @@
package resolvers
import (
"github.com/tribalwarshelp/api/ennoblement"
"github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/langversion"
"github.com/tribalwarshelp/api/liveennoblement"
@ -17,6 +18,7 @@ type Resolver struct {
TribeUcase tribe.Usecase
VillageUcase village.Usecase
LiveEnnoblementUcase liveennoblement.Usecase
EnnoblementUcase ennoblement.Usecase
}
// Query returns generated.QueryResolver implementation.
@ -26,10 +28,12 @@ func (r *Resolver) Village() generated.VillageResolver { return &villageResolver
func (r *Resolver) LiveEnnoblement() generated.LiveEnnoblementResolver {
return &liveEnnoblementResolver{r}
}
func (r *Resolver) Server() generated.ServerResolver { return &serverResolver{r} }
func (r *Resolver) Ennoblement() generated.EnnoblementResolver { return &ennoblementResolver{r} }
func (r *Resolver) Server() generated.ServerResolver { return &serverResolver{r} }
type queryResolver struct{ *Resolver }
type playerResolver struct{ *Resolver }
type villageResolver struct{ *Resolver }
type liveEnnoblementResolver struct{ *Resolver }
type ennoblementResolver struct{ *Resolver }
type serverResolver struct{ *Resolver }

View File

@ -4,8 +4,6 @@ import (
"context"
"time"
"github.com/tribalwarshelp/api/utils"
"github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/api/graphql/generated"
@ -22,15 +20,18 @@ func (r *serverResolver) LangVersion(ctx context.Context, obj *models.Server) (*
}
func (r *serverResolver) DataUpdatedAt(ctx context.Context, obj *models.Server) (*time.Time, error) {
loaders := middleware.DataLoadersFromContext(ctx)
if loaders != nil {
lv, err := loaders.LangVersionByTag.Load(obj.LangVersionTag.String())
if err == nil {
dataUpdatedAt := obj.DataUpdatedAt.In(utils.GetLocation(lv.Timezone))
return &dataUpdatedAt, nil
}
}
return &obj.DataUpdatedAt, nil
t := formatDate(context.Background(), obj.LangVersionTag, obj.DataUpdatedAt)
return &t, nil
}
func (r *serverResolver) HistoryUpdatedAt(ctx context.Context, obj *models.Server) (*time.Time, error) {
t := formatDate(context.Background(), obj.LangVersionTag, obj.HistoryUpdatedAt)
return &t, nil
}
func (r *serverResolver) StatsUpdatedAt(ctx context.Context, obj *models.Server) (*time.Time, error) {
t := formatDate(context.Background(), obj.LangVersionTag, obj.StatsUpdatedAt)
return &t, nil
}
func (r *queryResolver) Servers(ctx context.Context, filter *models.ServerFilter) (*generated.ServersList, error) {

View File

@ -3,9 +3,7 @@ package resolvers
import (
"context"
"github.com/99designs/gqlgen/graphql"
"github.com/tribalwarshelp/api/graphql/generated"
"github.com/tribalwarshelp/api/middleware"
"github.com/tribalwarshelp/shared/models"
)
@ -14,19 +12,7 @@ func (r *villageResolver) Player(ctx context.Context, obj *models.Village) (*mod
return obj.Player, nil
}
if server, ok := getServer(graphql.GetFieldContext(ctx)); ok {
dataloaders := middleware.ServerDataLoadersFromContext(ctx)
if dataloaders != nil {
if dataloader, ok := dataloaders[server]; ok {
tribe, _ := dataloader.PlayerByID.Load(obj.PlayerID)
if tribe != nil {
return tribe, nil
}
}
}
}
return nil, nil
return getPlayer(ctx, obj.PlayerID), nil
}
func (r *queryResolver) Villages(ctx context.Context, server string, filter *models.VillageFilter) (*generated.VillagesList, error) {

View File

@ -0,0 +1,42 @@
type Ennoblement {
village: Village @goField(forceResolver: true)
newOwner: Player @goField(forceResolver: true)
newOwnerTribe: Tribe @goField(forceResolver: true)
oldOwner: Player @goField(forceResolver: true)
oldOwnerTribe: Tribe @goField(forceResolver: true)
ennobledAt: Time! @goField(forceResolver: true)
}
type EnnoblementsList {
items: [Ennoblement!]
total: Int!
}
input EnnoblementFilter {
villageID: [Int!]
villageIDNEQ: [Int!]
newOwnerID: [Int!]
newOwnerIDNEQ: [Int!]
newOwnerTribeID: [Int!]
newOwnerTribeIDNEQ: [Int!]
oldOwnerID: [Int!]
oldOwnerIDNEQ: [Int!]
oldOwnerTribeID: [Int!]
oldOwnerTribeIDNEQ: [Int!]
ennobledAt: Time
ennobledAtGT: Time
ennobledAtGTE: Time
ennobledAtLT: Time
ennobledAtLTE: Time
offset: Int
limit: Int
sort: String
}
extend type Query {
ennoblements(server: String!, filter: EnnoblementFilter): EnnoblementsList!
}

View File

@ -7,11 +7,19 @@ type Server {
id: Int!
key: String!
status: ServerStatus!
numberOfPlayers: Int!
numberOfTribes: Int!
numberOfVillages: Int!
langVersion: LangVersion @goField(forceResolver: true)
config: ServerConfig!
unitConfig: UnitConfig!
buildingConfig: BuildingConfig!
dataUpdatedAt: Time! @goField(forceResolver: true)
historyUpdatedAt: Time! @goField(forceResolver: true)
statsUpdatedAt: Time! @goField(forceResolver: true)
}
type ServersList {

View File

@ -17,6 +17,8 @@ import (
"github.com/tribalwarshelp/api/graphql/dataloaders"
ennoblementrepo "github.com/tribalwarshelp/api/ennoblement/repository"
ennoblementucase "github.com/tribalwarshelp/api/ennoblement/usecase"
langversionrepo "github.com/tribalwarshelp/api/langversion/repository"
langversionucase "github.com/tribalwarshelp/api/langversion/usecase"
liveennoblementrepo "github.com/tribalwarshelp/api/liveennoblement/repository"
@ -83,6 +85,7 @@ func main() {
tribeRepo := triberepo.NewPGRepository(db)
playerRepo := playerrepo.NewPGRepository(db)
villageRepo := villagerepo.NewPGRepository(db)
ennoblementRepo := ennoblementrepo.NewPGRepository(db)
liveennoblementRepo := liveennoblementrepo.NewPGRepository(db, redisClient)
router := gin.Default()
@ -101,6 +104,7 @@ func main() {
TribeUcase: tribeucase.New(tribeRepo),
PlayerUcase: playerucase.New(playerRepo),
VillageUcase: villageucase.New(villageRepo),
EnnoblementUcase: ennoblementucase.New(ennoblementRepo),
LiveEnnoblementUcase: liveennoblementucase.New(liveennoblementRepo),
},
})

View File

@ -0,0 +1,12 @@
package utils
import (
"github.com/tribalwarshelp/shared/models"
)
func LanguageTagFromServerKey(key string) models.LanguageTag {
if len(key) < 2 {
return ""
}
return models.LanguageTag(key[0:2])
}