allow to sort DailyTribeStats, DailyPlayerStats, Players, Villages by relationship fields | improve SanitizeSort functionality

This commit is contained in:
Dawid Wysokiński 2020-07-18 11:02:30 +02:00
parent 9eef73379f
commit dd9f7bd880
9 changed files with 76 additions and 9 deletions

View File

@ -31,18 +31,31 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg dailyplayerstats.FetchC
Limit(cfg.Filter.Limit).
Offset(cfg.Filter.Offset)
order := []string{}
if cfg.Filter.Sort != "" {
query = query.Order(cfg.Filter.Sort)
order = append(order, cfg.Filter.Sort)
}
if cfg.Filter.PlayerFilter != nil {
query = query.Relation("Player._").WhereStruct(cfg.Filter.PlayerFilter)
if cfg.Filter.PlayerFilter.Sort != "" {
order = append(order, fmt.Sprintf("player.%s", cfg.Filter.PlayerFilter.Sort))
}
if cfg.Filter.PlayerFilter.TribeFilter != nil {
query = query.
Join("LEFT JOIN ?SERVER.tribes AS tribe ON tribe.id = player.tribe_id").
WhereStruct(cfg.Filter.PlayerFilter.TribeFilter)
if cfg.Filter.PlayerFilter.TribeFilter.Sort != "" {
order = append(order, fmt.Sprintf("tribe.%s", cfg.Filter.PlayerFilter.TribeFilter.Sort))
}
}
}
query = query.Order(order...)
}
if cfg.Count {

View File

@ -24,6 +24,12 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.D
filter.Limit = dailyplayerstats.PaginationLimit
}
filter.Sort = utils.SanitizeSort(filter.Sort)
if filter.PlayerFilter != nil {
filter.PlayerFilter.Sort = utils.SanitizeSort(filter.PlayerFilter.Sort)
if filter.PlayerFilter.TribeFilter != nil {
filter.PlayerFilter.TribeFilter.Sort = utils.SanitizeSort(filter.PlayerFilter.TribeFilter.Sort)
}
}
return ucase.repo.Fetch(ctx, dailyplayerstats.FetchConfig{
Server: server,
Filter: filter,

View File

@ -31,13 +31,21 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg dailytribestats.FetchCo
Limit(cfg.Filter.Limit).
Offset(cfg.Filter.Offset)
order := []string{}
if cfg.Filter.Sort != "" {
query = query.Order(cfg.Filter.Sort)
order = append(order, cfg.Filter.Sort)
}
if cfg.Filter.TribeFilter != nil {
query = query.Relation("Tribe._").WhereStruct(cfg.Filter.TribeFilter)
if cfg.Filter.TribeFilter.Sort != "" {
order = append(order, fmt.Sprintf("tribe.%s", cfg.Filter.TribeFilter.Sort))
}
}
query = query.Order(order...)
}
if cfg.Count {

View File

@ -24,6 +24,9 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.D
filter.Limit = dailytribestats.PaginationLimit
}
filter.Sort = utils.SanitizeSort(filter.Sort)
if filter.TribeFilter != nil {
filter.TribeFilter.Sort = utils.SanitizeSort(filter.TribeFilter.Sort)
}
return ucase.repo.Fetch(ctx, dailytribestats.FetchConfig{
Server: server,
Filter: filter,

View File

@ -31,17 +31,25 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg player.FetchConfig) ([]
Limit(cfg.Filter.Limit).
Offset(cfg.Filter.Offset)
if cfg.Filter.Sort != "" {
query = query.Order(cfg.Filter.Sort)
}
if cfg.Filter.Exists != nil {
query = query.Where("exists = ?", *cfg.Filter.Exists)
}
order := []string{}
if cfg.Filter.Sort != "" {
order = append(order, cfg.Filter.Sort)
}
if cfg.Filter.TribeFilter != nil {
query = query.Relation("Tribe._").WhereStruct(cfg.Filter.TribeFilter)
if cfg.Filter.TribeFilter.Sort != "" {
order = append(order, fmt.Sprintf("tribe.%s", cfg.Filter.TribeFilter.Sort))
}
}
query = query.Order(order...)
}
if cfg.Count {

View File

@ -25,6 +25,9 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.P
filter.Limit = player.PaginationLimit
}
filter.Sort = utils.SanitizeSort(filter.Sort)
if filter.TribeFilter != nil {
filter.TribeFilter.Sort = utils.SanitizeSort(filter.TribeFilter.Sort)
}
return ucase.repo.Fetch(ctx, player.FetchConfig{
Server: server,
Filter: filter,

View File

@ -1,12 +1,19 @@
package utils
import "strings"
import (
"regexp"
"strings"
)
var (
sortRegex = regexp.MustCompile(`^[\p{L}\_]+$`)
)
func SanitizeSort(sort string) string {
trimmed := strings.TrimSpace(sort)
splitted := strings.Split(trimmed, " ")
length := len(splitted)
if length != 2 {
if length != 2 || !sortRegex.Match([]byte(splitted[0])) {
return ""
}
keyword := "ASC"

View File

@ -52,18 +52,31 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg village.FetchConfig) ([
query = query.Where("y < ?", cfg.Filter.YLT)
}
order := []string{}
if cfg.Filter.Sort != "" {
query = query.Order(cfg.Filter.Sort)
order = append(order, cfg.Filter.Sort)
}
if cfg.Filter.PlayerFilter != nil {
query = query.Relation("Player._").WhereStruct(cfg.Filter.PlayerFilter)
if cfg.Filter.PlayerFilter.Sort != "" {
order = append(order, fmt.Sprintf("player.%s", cfg.Filter.PlayerFilter.Sort))
}
if cfg.Filter.PlayerFilter.TribeFilter != nil {
query = query.
Join("LEFT JOIN ?SERVER.tribes AS tribe ON tribe.id = player.tribe_id").
WhereStruct(cfg.Filter.PlayerFilter.TribeFilter)
if cfg.Filter.PlayerFilter.TribeFilter.Sort != "" {
order = append(order, fmt.Sprintf("tribe.%s", cfg.Filter.PlayerFilter.TribeFilter.Sort))
}
}
}
query = query.Order(order...)
}
total := 0

View File

@ -25,6 +25,12 @@ func (ucase *usecase) Fetch(ctx context.Context, server string, filter *models.V
filter.Limit = village.PaginationLimit
}
filter.Sort = utils.SanitizeSort(filter.Sort)
if filter.PlayerFilter != nil {
filter.PlayerFilter.Sort = utils.SanitizeSort(filter.PlayerFilter.Sort)
if filter.PlayerFilter.TribeFilter != nil {
filter.PlayerFilter.TribeFilter.Sort = utils.SanitizeSort(filter.PlayerFilter.TribeFilter.Sort)
}
}
return ucase.repo.Fetch(ctx, village.FetchConfig{
Server: server,
Count: true,