refactor: repositories - simplify how cursor/sort is applied
ci/woodpecker/push/govulncheck Pipeline was successful Details
ci/woodpecker/push/test Pipeline was successful Details

This commit is contained in:
Dawid Wysokiński 2024-03-14 08:06:17 +01:00
parent 7a206d746e
commit 3a903741f5
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
11 changed files with 379 additions and 368 deletions

View File

@ -5,6 +5,10 @@ run:
linters: linters:
disable-all: true disable-all: true
enable: enable:
- gochecknoinits
- goprintffuncname
- nosprintfhostport
- spancheck
- gocyclo - gocyclo
- asasalint - asasalint
- asciicheck - asciicheck
@ -54,6 +58,7 @@ linters:
- sloglint - sloglint
- revive - revive
- gomnd - gomnd
- forbidigo
linters-settings: linters-settings:
gocyclo: gocyclo:
@ -65,6 +70,13 @@ linters-settings:
bun: snake bun: snake
lll: lll:
line-length: 120 line-length: 120
forbidigo:
forbid:
- p: ^print.*$
msg: Do not commit print statements.
- p: ^fmt\.Print.*$
msg: Do not commit print statements.
analyze-types: true
govet: govet:
enable: enable:
- asmdecl - asmdecl
@ -291,7 +303,7 @@ linters-settings:
disabled: false disabled: false
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#indent-error-flow # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#indent-error-flow
- name: indent-error-flow - name: indent-error-flow
severity: warning severity: error
disabled: false disabled: false
arguments: arguments:
- preserveScope - preserveScope
@ -477,6 +489,9 @@ issues:
- gocyclo - gocyclo
- path: _test\.go - path: _test\.go
text: add-constant text: add-constant
- path: bun/migrations
linters:
- gochecknoinits
- linters: - linters:
- lll - lll
source: "^//go:generate " source: "^//go:generate "

View File

@ -38,6 +38,10 @@ const (
sortDirectionDESC sortDirectionDESC
) )
func (sd sortDirection) Bun() bun.Safe {
return bun.Safe(sd.String())
}
func (sd sortDirection) String() string { func (sd sortDirection) String() string {
switch sd { switch sd {
case sortDirectionASC: case sortDirectionASC:
@ -51,7 +55,7 @@ func (sd sortDirection) String() string {
type cursorPaginationApplierDataElement struct { type cursorPaginationApplierDataElement struct {
unique bool unique bool
column string column bun.Safe
direction sortDirection direction sortDirection
value any value any
} }
@ -86,10 +90,10 @@ func (a cursorPaginationApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
for j := 0; j < i; j++ { for j := 0; j < i; j++ {
prev := a.data[j] prev := a.data[j]
q = q.Where("? = ?", bun.Safe(prev.column), prev.value) q = q.Where("? = ?", prev.column, prev.value)
} }
column := bun.Safe(current.column) column := current.column
greaterSymbol := bun.Safe(">") greaterSymbol := bun.Safe(">")
lessSymbol := bun.Safe("<") lessSymbol := bun.Safe("<")

View File

@ -112,7 +112,6 @@ type listEnnoblementsParamsApplier struct {
params domain.ListEnnoblementsParams params domain.ListEnnoblementsParams
} }
//nolint:gocyclo
func (a listEnnoblementsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery { func (a listEnnoblementsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 { if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 {
q = q.Where("ennoblement.server_key IN (?)", bun.In(serverKeys)) q = q.Where("ennoblement.server_key IN (?)", bun.In(serverKeys))
@ -145,22 +144,12 @@ func (a listEnnoblementsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuer
} }
for _, s := range a.params.Sort() { for _, s := range a.params.Sort() {
switch s { column, dir, err := a.sortToColumnAndDirection(s)
case domain.EnnoblementSortCreatedAtASC: if err != nil {
q = q.Order("ennoblement.created_at ASC") return q.Err(err)
case domain.EnnoblementSortCreatedAtDESC:
q = q.Order("ennoblement.created_at DESC")
case domain.EnnoblementSortIDASC:
q = q.Order("ennoblement.id ASC")
case domain.EnnoblementSortIDDESC:
q = q.Order("ennoblement.id DESC")
case domain.EnnoblementSortServerKeyASC:
q = q.Order("ennoblement.server_key ASC")
case domain.EnnoblementSortServerKeyDESC:
q = q.Order("ennoblement.server_key DESC")
default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
q.OrderExpr("? ?", column, dir.Bun())
} }
return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor) return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor)
@ -179,35 +168,25 @@ func (a listEnnoblementsParamsApplier) applyCursor(q *bun.SelectQuery) *bun.Sele
} }
for _, s := range sort { for _, s := range sort {
var err error
var el cursorPaginationApplierDataElement var el cursorPaginationApplierDataElement
el.column, el.direction, err = a.sortToColumnAndDirection(s)
if err != nil {
return q.Err(err)
}
switch s { switch s {
case domain.EnnoblementSortIDASC: case domain.EnnoblementSortIDASC,
domain.EnnoblementSortIDDESC:
el.value = cursor.ID() el.value = cursor.ID()
el.unique = true el.unique = true
el.column = "ennoblement.id" case domain.EnnoblementSortServerKeyASC,
el.direction = sortDirectionASC domain.EnnoblementSortServerKeyDESC:
case domain.EnnoblementSortIDDESC:
el.value = cursor.ID()
el.unique = true
el.column = "ennoblement.id"
el.direction = sortDirectionDESC
case domain.EnnoblementSortServerKeyASC:
el.value = cursor.ServerKey() el.value = cursor.ServerKey()
el.column = "ennoblement.server_key" case domain.EnnoblementSortCreatedAtASC,
el.direction = sortDirectionASC domain.EnnoblementSortCreatedAtDESC:
case domain.EnnoblementSortServerKeyDESC:
el.value = cursor.ServerKey()
el.column = "ennoblement.server_key"
el.direction = sortDirectionDESC
case domain.EnnoblementSortCreatedAtASC:
el.value = cursor.CreatedAt() el.value = cursor.CreatedAt()
el.column = "ennoblement.created_at"
el.direction = sortDirectionASC
case domain.EnnoblementSortCreatedAtDESC:
el.value = cursor.CreatedAt()
el.column = "ennoblement.created_at"
el.direction = sortDirectionDESC
default: default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)) return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
@ -217,3 +196,24 @@ func (a listEnnoblementsParamsApplier) applyCursor(q *bun.SelectQuery) *bun.Sele
return q.Apply(cursorApplier.apply) return q.Apply(cursorApplier.apply)
} }
func (a listEnnoblementsParamsApplier) sortToColumnAndDirection(
s domain.EnnoblementSort,
) (bun.Safe, sortDirection, error) {
switch s {
case domain.EnnoblementSortCreatedAtASC:
return "ennoblement.created_at", sortDirectionASC, nil
case domain.EnnoblementSortCreatedAtDESC:
return "ennoblement.created_at", sortDirectionDESC, nil
case domain.EnnoblementSortIDASC:
return "ennoblement.id", sortDirectionASC, nil
case domain.EnnoblementSortIDDESC:
return "ennoblement.id", sortDirectionDESC, nil
case domain.EnnoblementSortServerKeyASC:
return "ennoblement.server_key", sortDirectionASC, nil
case domain.EnnoblementSortServerKeyDESC:
return "ennoblement.server_key", sortDirectionDESC, nil
default:
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
}
}

View File

@ -158,7 +158,6 @@ type listPlayersParamsApplier struct {
params domain.ListPlayersParams params domain.ListPlayersParams
} }
//nolint:gocyclo
func (a listPlayersParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery { func (a listPlayersParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
if ids := a.params.IDs(); len(ids) > 0 { if ids := a.params.IDs(); len(ids) > 0 {
q = q.Where("player.id IN (?)", bun.In(ids)) q = q.Where("player.id IN (?)", bun.In(ids))
@ -185,42 +184,12 @@ func (a listPlayersParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
} }
for _, s := range a.params.Sort() { for _, s := range a.params.Sort() {
switch s { column, dir, err := a.sortToColumnAndDirection(s)
case domain.PlayerSortIDASC: if err != nil {
q = q.Order("player.id ASC") return q.Err(err)
case domain.PlayerSortIDDESC:
q = q.Order("player.id DESC")
case domain.PlayerSortServerKeyASC:
q = q.Order("player.server_key ASC")
case domain.PlayerSortServerKeyDESC:
q = q.Order("player.server_key DESC")
case domain.PlayerSortODScoreAttASC:
q = q.Order("player.score_att ASC")
case domain.PlayerSortODScoreAttDESC:
q = q.Order("player.score_att DESC")
case domain.PlayerSortODScoreDefASC:
q = q.Order("player.score_def ASC")
case domain.PlayerSortODScoreDefDESC:
q = q.Order("player.score_def DESC")
case domain.PlayerSortODScoreSupASC:
q = q.Order("player.score_sup ASC")
case domain.PlayerSortODScoreSupDESC:
q = q.Order("player.score_sup DESC")
case domain.PlayerSortODScoreTotalASC:
q = q.Order("player.score_total ASC")
case domain.PlayerSortODScoreTotalDESC:
q = q.Order("player.score_total DESC")
case domain.PlayerSortPointsASC:
q = q.Order("player.points ASC")
case domain.PlayerSortPointsDESC:
q = q.Order("player.points DESC")
case domain.PlayerSortDeletedAtASC:
q = q.OrderExpr("COALESCE(player.deleted_at, ?) ASC", time.Time{})
case domain.PlayerSortDeletedAtDESC:
q = q.OrderExpr("COALESCE(player.deleted_at, ?) DESC", time.Time{})
default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
q.OrderExpr("? ?", column, dir.Bun())
} }
return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor) return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor)
@ -240,75 +209,40 @@ func (a listPlayersParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQue
} }
for _, s := range sort { for _, s := range sort {
var err error
var el cursorPaginationApplierDataElement var el cursorPaginationApplierDataElement
el.column, el.direction, err = a.sortToColumnAndDirection(s)
if err != nil {
return q.Err(err)
}
switch s { switch s {
case domain.PlayerSortIDASC: case domain.PlayerSortIDASC,
domain.PlayerSortIDDESC:
el.value = cursor.ID() el.value = cursor.ID()
el.unique = true el.unique = true
el.column = "player.id" case domain.PlayerSortServerKeyASC,
el.direction = sortDirectionASC domain.PlayerSortServerKeyDESC:
case domain.PlayerSortIDDESC:
el.value = cursor.ID()
el.unique = true
el.column = "player.id"
el.direction = sortDirectionDESC
case domain.PlayerSortServerKeyASC:
el.value = cursor.ServerKey() el.value = cursor.ServerKey()
el.column = "player.server_key" case domain.PlayerSortODScoreAttASC,
el.direction = sortDirectionASC domain.PlayerSortODScoreAttDESC:
case domain.PlayerSortServerKeyDESC:
el.value = cursor.ServerKey()
el.column = "player.server_key"
el.direction = sortDirectionDESC
case domain.PlayerSortODScoreAttASC:
el.value = cursor.ODScoreAtt() el.value = cursor.ODScoreAtt()
el.column = "player.score_att" case domain.PlayerSortODScoreDefASC,
el.direction = sortDirectionASC domain.PlayerSortODScoreDefDESC:
case domain.PlayerSortODScoreAttDESC:
el.value = cursor.ODScoreAtt()
el.column = "player.score_att"
el.direction = sortDirectionDESC
case domain.PlayerSortODScoreDefASC:
el.value = cursor.ODScoreDef() el.value = cursor.ODScoreDef()
el.column = "player.score_def" case domain.PlayerSortODScoreSupASC,
el.direction = sortDirectionASC domain.PlayerSortODScoreSupDESC:
case domain.PlayerSortODScoreDefDESC:
el.value = cursor.ODScoreDef()
el.column = "player.score_def"
el.direction = sortDirectionDESC
case domain.PlayerSortODScoreSupASC:
el.value = cursor.ODScoreSup() el.value = cursor.ODScoreSup()
el.column = "player.score_sup" case domain.PlayerSortODScoreTotalASC,
el.direction = sortDirectionASC domain.PlayerSortODScoreTotalDESC:
case domain.PlayerSortODScoreSupDESC:
el.value = cursor.ODScoreSup()
el.column = "player.score_sup"
el.direction = sortDirectionDESC
case domain.PlayerSortODScoreTotalASC:
el.value = cursor.ODScoreTotal() el.value = cursor.ODScoreTotal()
el.column = "player.score_total" case domain.PlayerSortPointsASC,
el.direction = sortDirectionASC domain.PlayerSortPointsDESC:
case domain.PlayerSortODScoreTotalDESC:
el.value = cursor.ODScoreTotal()
el.column = "player.score_total"
el.direction = sortDirectionDESC
case domain.PlayerSortPointsASC:
el.value = cursor.Points() el.value = cursor.Points()
el.column = "player.points" case domain.PlayerSortDeletedAtASC,
el.direction = sortDirectionASC domain.PlayerSortDeletedAtDESC:
case domain.PlayerSortPointsDESC:
el.value = cursor.Points()
el.column = "player.points"
el.direction = sortDirectionDESC
case domain.PlayerSortDeletedAtASC:
el.value = cursor.DeletedAt() el.value = cursor.DeletedAt()
el.column = "COALESCE(player.deleted_at, '0001-01-01 00:00:00+00:00')"
el.direction = sortDirectionASC
case domain.PlayerSortDeletedAtDESC:
el.value = cursor.DeletedAt()
el.column = "COALESCE(player.deleted_at, '0001-01-01 00:00:00+00:00')"
el.direction = sortDirectionDESC
default: default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)) return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
@ -318,3 +252,45 @@ func (a listPlayersParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQue
return q.Apply(cursorApplier.apply) return q.Apply(cursorApplier.apply)
} }
//nolint:gocyclo
func (a listPlayersParamsApplier) sortToColumnAndDirection(
s domain.PlayerSort,
) (bun.Safe, sortDirection, error) {
switch s {
case domain.PlayerSortIDASC:
return "player.id", sortDirectionASC, nil
case domain.PlayerSortIDDESC:
return "player.id", sortDirectionDESC, nil
case domain.PlayerSortServerKeyASC:
return "player.server_key", sortDirectionASC, nil
case domain.PlayerSortServerKeyDESC:
return "player.server_key", sortDirectionDESC, nil
case domain.PlayerSortODScoreAttASC:
return "player.score_att", sortDirectionASC, nil
case domain.PlayerSortODScoreAttDESC:
return "player.score_att", sortDirectionDESC, nil
case domain.PlayerSortODScoreDefASC:
return "player.score_def", sortDirectionASC, nil
case domain.PlayerSortODScoreDefDESC:
return "player.score_def", sortDirectionDESC, nil
case domain.PlayerSortODScoreSupASC:
return "player.score_sup", sortDirectionASC, nil
case domain.PlayerSortODScoreSupDESC:
return "player.score_sup", sortDirectionDESC, nil
case domain.PlayerSortODScoreTotalASC:
return "player.score_total", sortDirectionASC, nil
case domain.PlayerSortODScoreTotalDESC:
return "player.score_total", sortDirectionDESC, nil
case domain.PlayerSortPointsASC:
return "player.points", sortDirectionASC, nil
case domain.PlayerSortPointsDESC:
return "player.points", sortDirectionDESC, nil
case domain.PlayerSortDeletedAtASC:
return "COALESCE(player.deleted_at, '0001-01-01 00:00:00+00:00')", sortDirectionASC, nil
case domain.PlayerSortDeletedAtDESC:
return "COALESCE(player.deleted_at, '0001-01-01 00:00:00+00:00')", sortDirectionDESC, nil
default:
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
}
}

View File

@ -76,30 +76,40 @@ type listPlayerSnapshotsParamsApplier struct {
params domain.ListPlayerSnapshotsParams params domain.ListPlayerSnapshotsParams
} }
//nolint:gocyclo
func (a listPlayerSnapshotsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery { func (a listPlayerSnapshotsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 { if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 {
q = q.Where("ps.server_key IN (?)", bun.In(serverKeys)) q = q.Where("ps.server_key IN (?)", bun.In(serverKeys))
} }
for _, s := range a.params.Sort() { for _, s := range a.params.Sort() {
switch s { column, dir, err := a.sortToColumnAndDirection(s)
case domain.PlayerSnapshotSortDateASC: if err != nil {
q = q.Order("ps.date ASC") return q.Err(err)
case domain.PlayerSnapshotSortDateDESC:
q = q.Order("ps.date DESC")
case domain.PlayerSnapshotSortIDASC:
q = q.Order("ps.id ASC")
case domain.PlayerSnapshotSortIDDESC:
q = q.Order("ps.id DESC")
case domain.PlayerSnapshotSortServerKeyASC:
q = q.Order("ps.server_key ASC")
case domain.PlayerSnapshotSortServerKeyDESC:
q = q.Order("ps.server_key DESC")
default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
q.OrderExpr("? ?", column, dir.Bun())
} }
return q.Limit(a.params.Limit()).Offset(a.params.Offset()) return q.Limit(a.params.Limit()).Offset(a.params.Offset())
} }
func (a listPlayerSnapshotsParamsApplier) sortToColumnAndDirection(
s domain.PlayerSnapshotSort,
) (bun.Safe, sortDirection, error) {
switch s {
case domain.PlayerSnapshotSortDateASC:
return "ps.date", sortDirectionASC, nil
case domain.PlayerSnapshotSortDateDESC:
return "ps.date", sortDirectionDESC, nil
case domain.PlayerSnapshotSortIDASC:
return "ps.id", sortDirectionASC, nil
case domain.PlayerSnapshotSortIDDESC:
return "ps.id", sortDirectionDESC, nil
case domain.PlayerSnapshotSortServerKeyASC:
return "ps.server_key", sortDirectionASC, nil
case domain.PlayerSnapshotSortServerKeyDESC:
return "ps.server_key", sortDirectionDESC, nil
default:
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
}
}

View File

@ -185,7 +185,6 @@ type listServersParamsApplier struct {
params domain.ListServersParams params domain.ListServersParams
} }
//nolint:gocyclo
func (a listServersParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery { func (a listServersParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
if keys := a.params.Keys(); len(keys) > 0 { if keys := a.params.Keys(); len(keys) > 0 {
q = q.Where("server.key IN (?)", bun.In(keys)) q = q.Where("server.key IN (?)", bun.In(keys))
@ -218,18 +217,12 @@ func (a listServersParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
} }
for _, s := range a.params.Sort() { for _, s := range a.params.Sort() {
switch s { column, dir, err := a.sortToColumnAndDirection(s)
case domain.ServerSortKeyASC: if err != nil {
q = q.Order("server.key ASC") return q.Err(err)
case domain.ServerSortKeyDESC:
q = q.Order("server.key DESC")
case domain.ServerSortOpenASC:
q = q.Order("server.open ASC")
case domain.ServerSortOpenDESC:
q = q.Order("server.open DESC")
default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
q.OrderExpr("? ?", column, dir.Bun())
} }
return q.Apply(a.applyCursor).Limit(a.params.Limit() + 1) return q.Apply(a.applyCursor).Limit(a.params.Limit() + 1)
@ -248,29 +241,22 @@ func (a listServersParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQue
} }
for _, s := range sort { for _, s := range sort {
var err error
var el cursorPaginationApplierDataElement var el cursorPaginationApplierDataElement
el.column, el.direction, err = a.sortToColumnAndDirection(s)
if err != nil {
return q.Err(err)
}
switch s { switch s {
case domain.ServerSortKeyASC: case domain.ServerSortKeyASC,
domain.ServerSortKeyDESC:
el.value = cursor.Key() el.value = cursor.Key()
el.unique = true el.unique = true
el.column = "server.key" case domain.ServerSortOpenASC,
el.direction = sortDirectionASC domain.ServerSortOpenDESC:
case domain.ServerSortKeyDESC:
el.value = cursor.Key()
el.unique = true
el.column = "server.key"
el.direction = sortDirectionDESC
case domain.ServerSortOpenASC:
el.value = cursor.Open() el.value = cursor.Open()
el.unique = false
el.column = "server.open"
el.direction = sortDirectionASC
case domain.ServerSortOpenDESC:
el.value = cursor.Open()
el.unique = false
el.column = "server.open"
el.direction = sortDirectionDESC
default: default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)) return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
@ -280,3 +266,20 @@ func (a listServersParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQue
return q.Apply(cursorApplier.apply) return q.Apply(cursorApplier.apply)
} }
func (a listServersParamsApplier) sortToColumnAndDirection(
s domain.ServerSort,
) (bun.Safe, sortDirection, error) {
switch s {
case domain.ServerSortKeyASC:
return "server.key", sortDirectionASC, nil
case domain.ServerSortKeyDESC:
return "server.key", sortDirectionDESC, nil
case domain.ServerSortOpenASC:
return "server.open", sortDirectionASC, nil
case domain.ServerSortOpenDESC:
return "server.open", sortDirectionDESC, nil
default:
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
}
}

View File

@ -155,7 +155,6 @@ type listTribesParamsApplier struct {
params domain.ListTribesParams params domain.ListTribesParams
} }
//nolint:gocyclo
func (a listTribesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery { func (a listTribesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
if ids := a.params.IDs(); len(ids) > 0 { if ids := a.params.IDs(); len(ids) > 0 {
q = q.Where("tribe.id IN (?)", bun.In(ids)) q = q.Where("tribe.id IN (?)", bun.In(ids))
@ -178,42 +177,12 @@ func (a listTribesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
} }
for _, s := range a.params.Sort() { for _, s := range a.params.Sort() {
switch s { column, dir, err := a.sortToColumnAndDirection(s)
case domain.TribeSortIDASC: if err != nil {
q = q.Order("tribe.id ASC") return q.Err(err)
case domain.TribeSortIDDESC:
q = q.Order("tribe.id DESC")
case domain.TribeSortServerKeyASC:
q = q.Order("tribe.server_key ASC")
case domain.TribeSortServerKeyDESC:
q = q.Order("tribe.server_key DESC")
case domain.TribeSortODScoreAttASC:
q = q.Order("tribe.score_att ASC")
case domain.TribeSortODScoreAttDESC:
q = q.Order("tribe.score_att DESC")
case domain.TribeSortODScoreDefASC:
q = q.Order("tribe.score_def ASC")
case domain.TribeSortODScoreDefDESC:
q = q.Order("tribe.score_def DESC")
case domain.TribeSortODScoreTotalASC:
q = q.Order("tribe.score_total ASC")
case domain.TribeSortODScoreTotalDESC:
q = q.Order("tribe.score_total DESC")
case domain.TribeSortPointsASC:
q = q.Order("tribe.points ASC")
case domain.TribeSortPointsDESC:
q = q.Order("tribe.points DESC")
case domain.TribeSortDominanceASC:
q = q.Order("tribe.dominance ASC")
case domain.TribeSortDominanceDESC:
q = q.Order("tribe.dominance DESC")
case domain.TribeSortDeletedAtASC:
q = q.OrderExpr("COALESCE(tribe.deleted_at, ?) ASC", time.Time{})
case domain.TribeSortDeletedAtDESC:
q = q.OrderExpr("COALESCE(tribe.deleted_at, ?) DESC", time.Time{})
default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
q.OrderExpr("? ?", column, dir.Bun())
} }
return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor) return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor)
@ -233,75 +202,40 @@ func (a listTribesParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQuer
} }
for _, s := range sort { for _, s := range sort {
var err error
var el cursorPaginationApplierDataElement var el cursorPaginationApplierDataElement
el.column, el.direction, err = a.sortToColumnAndDirection(s)
if err != nil {
return q.Err(err)
}
switch s { switch s {
case domain.TribeSortIDASC: case domain.TribeSortIDASC,
domain.TribeSortIDDESC:
el.value = cursor.ID() el.value = cursor.ID()
el.unique = true el.unique = true
el.column = "tribe.id" case domain.TribeSortServerKeyASC,
el.direction = sortDirectionASC domain.TribeSortServerKeyDESC:
case domain.TribeSortIDDESC:
el.value = cursor.ID()
el.unique = true
el.column = "tribe.id"
el.direction = sortDirectionDESC
case domain.TribeSortServerKeyASC:
el.value = cursor.ServerKey() el.value = cursor.ServerKey()
el.column = "tribe.server_key" case domain.TribeSortODScoreAttASC,
el.direction = sortDirectionASC domain.TribeSortODScoreAttDESC:
case domain.TribeSortServerKeyDESC:
el.value = cursor.ServerKey()
el.column = "tribe.server_key"
el.direction = sortDirectionDESC
case domain.TribeSortODScoreAttASC:
el.value = cursor.ODScoreAtt() el.value = cursor.ODScoreAtt()
el.column = "tribe.score_att" case domain.TribeSortODScoreDefASC,
el.direction = sortDirectionASC domain.TribeSortODScoreDefDESC:
case domain.TribeSortODScoreAttDESC:
el.value = cursor.ODScoreAtt()
el.column = "tribe.score_att"
el.direction = sortDirectionDESC
case domain.TribeSortODScoreDefASC:
el.value = cursor.ODScoreDef() el.value = cursor.ODScoreDef()
el.column = "tribe.score_def" case domain.TribeSortODScoreTotalASC,
el.direction = sortDirectionASC domain.TribeSortODScoreTotalDESC:
case domain.TribeSortODScoreDefDESC:
el.value = cursor.ODScoreDef()
el.column = "tribe.score_def"
el.direction = sortDirectionDESC
case domain.TribeSortODScoreTotalASC:
el.value = cursor.ODScoreTotal() el.value = cursor.ODScoreTotal()
el.column = "tribe.score_total" case domain.TribeSortPointsASC,
el.direction = sortDirectionASC domain.TribeSortPointsDESC:
case domain.TribeSortODScoreTotalDESC:
el.value = cursor.ODScoreTotal()
el.column = "tribe.score_total"
el.direction = sortDirectionDESC
case domain.TribeSortPointsASC:
el.value = cursor.Points() el.value = cursor.Points()
el.column = "tribe.points" case domain.TribeSortDominanceASC,
el.direction = sortDirectionASC domain.TribeSortDominanceDESC:
case domain.TribeSortPointsDESC:
el.value = cursor.Points()
el.column = "tribe.points"
el.direction = sortDirectionDESC
case domain.TribeSortDominanceASC:
el.value = cursor.Dominance() el.value = cursor.Dominance()
el.column = "tribe.dominance" case domain.TribeSortDeletedAtASC,
el.direction = sortDirectionASC domain.TribeSortDeletedAtDESC:
case domain.TribeSortDominanceDESC:
el.value = cursor.Dominance()
el.column = "tribe.dominance"
el.direction = sortDirectionDESC
case domain.TribeSortDeletedAtASC:
el.value = cursor.DeletedAt() el.value = cursor.DeletedAt()
el.column = "COALESCE(tribe.deleted_at, '0001-01-01 00:00:00+00:00')"
el.direction = sortDirectionASC
case domain.TribeSortDeletedAtDESC:
el.value = cursor.DeletedAt()
el.column = "COALESCE(tribe.deleted_at, '0001-01-01 00:00:00+00:00')"
el.direction = sortDirectionDESC
default: default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)) return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
@ -311,3 +245,45 @@ func (a listTribesParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQuer
return q.Apply(cursorApplier.apply) return q.Apply(cursorApplier.apply)
} }
//nolint:gocyclo
func (a listTribesParamsApplier) sortToColumnAndDirection(
s domain.TribeSort,
) (bun.Safe, sortDirection, error) {
switch s {
case domain.TribeSortIDASC:
return "tribe.id", sortDirectionASC, nil
case domain.TribeSortIDDESC:
return "tribe.id", sortDirectionDESC, nil
case domain.TribeSortServerKeyASC:
return "tribe.server_key", sortDirectionASC, nil
case domain.TribeSortServerKeyDESC:
return "tribe.server_key", sortDirectionDESC, nil
case domain.TribeSortODScoreAttASC:
return "tribe.score_att", sortDirectionASC, nil
case domain.TribeSortODScoreAttDESC:
return "tribe.score_att", sortDirectionDESC, nil
case domain.TribeSortODScoreDefASC:
return "tribe.score_def", sortDirectionASC, nil
case domain.TribeSortODScoreDefDESC:
return "tribe.score_def", sortDirectionDESC, nil
case domain.TribeSortODScoreTotalASC:
return "tribe.score_total", sortDirectionASC, nil
case domain.TribeSortODScoreTotalDESC:
return "tribe.score_total", sortDirectionDESC, nil
case domain.TribeSortPointsASC:
return "tribe.points", sortDirectionASC, nil
case domain.TribeSortPointsDESC:
return "tribe.points", sortDirectionDESC, nil
case domain.TribeSortDominanceASC:
return "tribe.dominance", sortDirectionASC, nil
case domain.TribeSortDominanceDESC:
return "tribe.dominance", sortDirectionDESC, nil
case domain.TribeSortDeletedAtASC:
return "COALESCE(tribe.deleted_at, '0001-01-01 00:00:00+00:00')", sortDirectionASC, nil
case domain.TribeSortDeletedAtDESC:
return "COALESCE(tribe.deleted_at, '0001-01-01 00:00:00+00:00')", sortDirectionDESC, nil
default:
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
}
}

View File

@ -104,7 +104,6 @@ type listTribeChangesParamsApplier struct {
params domain.ListTribeChangesParams params domain.ListTribeChangesParams
} }
//nolint:gocyclo
func (a listTribeChangesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery { func (a listTribeChangesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 { if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 {
q = q.Where("tc.server_key IN (?)", bun.In(serverKeys)) q = q.Where("tc.server_key IN (?)", bun.In(serverKeys))
@ -130,22 +129,12 @@ func (a listTribeChangesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuer
} }
for _, s := range a.params.Sort() { for _, s := range a.params.Sort() {
switch s { column, dir, err := a.sortToColumnAndDirection(s)
case domain.TribeChangeSortCreatedAtASC: if err != nil {
q = q.Order("tc.created_at ASC") return q.Err(err)
case domain.TribeChangeSortCreatedAtDESC:
q = q.Order("tc.created_at DESC")
case domain.TribeChangeSortIDASC:
q = q.Order("tc.id ASC")
case domain.TribeChangeSortIDDESC:
q = q.Order("tc.id DESC")
case domain.TribeChangeSortServerKeyASC:
q = q.Order("tc.server_key ASC")
case domain.TribeChangeSortServerKeyDESC:
q = q.Order("tc.server_key DESC")
default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
q.OrderExpr("? ?", column, dir.Bun())
} }
return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor) return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor)
@ -164,35 +153,25 @@ func (a listTribeChangesParamsApplier) applyCursor(q *bun.SelectQuery) *bun.Sele
} }
for _, s := range sort { for _, s := range sort {
var err error
var el cursorPaginationApplierDataElement var el cursorPaginationApplierDataElement
el.column, el.direction, err = a.sortToColumnAndDirection(s)
if err != nil {
return q.Err(err)
}
switch s { switch s {
case domain.TribeChangeSortIDASC: case domain.TribeChangeSortIDASC,
domain.TribeChangeSortIDDESC:
el.value = cursor.ID() el.value = cursor.ID()
el.unique = true el.unique = true
el.column = "tc.id" case domain.TribeChangeSortServerKeyASC,
el.direction = sortDirectionASC domain.TribeChangeSortServerKeyDESC:
case domain.TribeChangeSortIDDESC:
el.value = cursor.ID()
el.unique = true
el.column = "tc.id"
el.direction = sortDirectionDESC
case domain.TribeChangeSortServerKeyASC:
el.value = cursor.ServerKey() el.value = cursor.ServerKey()
el.column = "tc.server_key" case domain.TribeChangeSortCreatedAtASC,
el.direction = sortDirectionASC domain.TribeChangeSortCreatedAtDESC:
case domain.TribeChangeSortServerKeyDESC:
el.value = cursor.ServerKey()
el.column = "tc.server_key"
el.direction = sortDirectionDESC
case domain.TribeChangeSortCreatedAtASC:
el.value = cursor.CreatedAt() el.value = cursor.CreatedAt()
el.column = "tc.created_at"
el.direction = sortDirectionASC
case domain.TribeChangeSortCreatedAtDESC:
el.value = cursor.CreatedAt()
el.column = "tc.created_at"
el.direction = sortDirectionDESC
default: default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)) return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
@ -202,3 +181,24 @@ func (a listTribeChangesParamsApplier) applyCursor(q *bun.SelectQuery) *bun.Sele
return q.Apply(cursorApplier.apply) return q.Apply(cursorApplier.apply)
} }
func (a listTribeChangesParamsApplier) sortToColumnAndDirection(
s domain.TribeChangeSort,
) (bun.Safe, sortDirection, error) {
switch s {
case domain.TribeChangeSortCreatedAtASC:
return "tc.created_at", sortDirectionASC, nil
case domain.TribeChangeSortCreatedAtDESC:
return "tc.created_at", sortDirectionDESC, nil
case domain.TribeChangeSortIDASC:
return "tc.id", sortDirectionASC, nil
case domain.TribeChangeSortIDDESC:
return "tc.id", sortDirectionDESC, nil
case domain.TribeChangeSortServerKeyASC:
return "tc.server_key", sortDirectionASC, nil
case domain.TribeChangeSortServerKeyDESC:
return "tc.server_key", sortDirectionDESC, nil
default:
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
}
}

View File

@ -75,30 +75,40 @@ type listTribeSnapshotsParamsApplier struct {
params domain.ListTribeSnapshotsParams params domain.ListTribeSnapshotsParams
} }
//nolint:gocyclo
func (a listTribeSnapshotsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery { func (a listTribeSnapshotsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 { if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 {
q = q.Where("ts.server_key IN (?)", bun.In(serverKeys)) q = q.Where("ts.server_key IN (?)", bun.In(serverKeys))
} }
for _, s := range a.params.Sort() { for _, s := range a.params.Sort() {
switch s { column, dir, err := a.sortToColumnAndDirection(s)
case domain.TribeSnapshotSortDateASC: if err != nil {
q = q.Order("ts.date ASC") return q.Err(err)
case domain.TribeSnapshotSortDateDESC:
q = q.Order("ts.date DESC")
case domain.TribeSnapshotSortIDASC:
q = q.Order("ts.id ASC")
case domain.TribeSnapshotSortIDDESC:
q = q.Order("ts.id DESC")
case domain.TribeSnapshotSortServerKeyASC:
q = q.Order("ts.server_key ASC")
case domain.TribeSnapshotSortServerKeyDESC:
q = q.Order("ts.server_key DESC")
default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
q.OrderExpr("? ?", column, dir.Bun())
} }
return q.Limit(a.params.Limit()).Offset(a.params.Offset()) return q.Limit(a.params.Limit()).Offset(a.params.Offset())
} }
func (a listTribeSnapshotsParamsApplier) sortToColumnAndDirection(
s domain.TribeSnapshotSort,
) (bun.Safe, sortDirection, error) {
switch s {
case domain.TribeSnapshotSortDateASC:
return "ts.date", sortDirectionASC, nil
case domain.TribeSnapshotSortDateDESC:
return "ts.date", sortDirectionDESC, nil
case domain.TribeSnapshotSortIDASC:
return "ts.id", sortDirectionASC, nil
case domain.TribeSnapshotSortIDDESC:
return "ts.id", sortDirectionDESC, nil
case domain.TribeSnapshotSortServerKeyASC:
return "ts.server_key", sortDirectionASC, nil
case domain.TribeSnapshotSortServerKeyDESC:
return "ts.server_key", sortDirectionDESC, nil
default:
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
}
}

View File

@ -50,14 +50,12 @@ func (a listVersionsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
} }
for _, s := range a.params.Sort() { for _, s := range a.params.Sort() {
switch s { column, dir, err := a.sortToColumnAndDirection(s)
case domain.VersionSortCodeASC: if err != nil {
q = q.Order("version.code ASC") return q.Err(err)
case domain.VersionSortCodeDESC:
q = q.Order("version.code DESC")
default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
q.OrderExpr("? ?", column, dir.Bun())
} }
return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor) return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor)
@ -76,19 +74,19 @@ func (a listVersionsParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQu
} }
for _, s := range sort { for _, s := range sort {
var err error
var el cursorPaginationApplierDataElement var el cursorPaginationApplierDataElement
el.column, el.direction, err = a.sortToColumnAndDirection(s)
if err != nil {
return q.Err(err)
}
switch s { switch s {
case domain.VersionSortCodeASC: case domain.VersionSortCodeASC,
domain.VersionSortCodeDESC:
el.value = cursor.Code() el.value = cursor.Code()
el.unique = true el.unique = true
el.column = "version.code"
el.direction = sortDirectionASC
case domain.VersionSortCodeDESC:
el.value = cursor.Code()
el.unique = true
el.column = "version.code"
el.direction = sortDirectionDESC
default: default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)) return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
@ -98,3 +96,16 @@ func (a listVersionsParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQu
return q.Apply(cursorApplier.apply) return q.Apply(cursorApplier.apply)
} }
func (a listVersionsParamsApplier) sortToColumnAndDirection(
s domain.VersionSort,
) (bun.Safe, sortDirection, error) {
switch s {
case domain.VersionSortCodeASC:
return "version.code", sortDirectionASC, nil
case domain.VersionSortCodeDESC:
return "version.code", sortDirectionDESC, nil
default:
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
}
}

View File

@ -176,18 +176,12 @@ func (a listVillagesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
} }
for _, s := range a.params.Sort() { for _, s := range a.params.Sort() {
switch s { column, dir, err := a.sortToColumnAndDirection(s)
case domain.VillageSortIDASC: if err != nil {
q = q.Order("village.id ASC") return q.Err(err)
case domain.VillageSortIDDESC:
q = q.Order("village.id DESC")
case domain.VillageSortServerKeyASC:
q = q.Order("village.server_key ASC")
case domain.VillageSortServerKeyDESC:
q = q.Order("village.server_key DESC")
default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
q.OrderExpr("? ?", column, dir.Bun())
} }
return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor) return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor)
@ -206,27 +200,22 @@ func (a listVillagesParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQu
} }
for _, s := range sort { for _, s := range sort {
var err error
var el cursorPaginationApplierDataElement var el cursorPaginationApplierDataElement
el.column, el.direction, err = a.sortToColumnAndDirection(s)
if err != nil {
return q.Err(err)
}
switch s { switch s {
case domain.VillageSortIDASC: case domain.VillageSortIDASC,
domain.VillageSortIDDESC:
el.value = cursor.ID() el.value = cursor.ID()
el.unique = true el.unique = true
el.column = "village.id" case domain.VillageSortServerKeyASC,
el.direction = sortDirectionASC domain.VillageSortServerKeyDESC:
case domain.VillageSortIDDESC:
el.value = cursor.ID()
el.unique = true
el.column = "village.id"
el.direction = sortDirectionDESC
case domain.VillageSortServerKeyASC:
el.value = cursor.ServerKey() el.value = cursor.ServerKey()
el.column = "village.server_key"
el.direction = sortDirectionASC
case domain.VillageSortServerKeyDESC:
el.value = cursor.ServerKey()
el.column = "village.server_key"
el.direction = sortDirectionDESC
default: default:
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)) return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
} }
@ -236,3 +225,20 @@ func (a listVillagesParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQu
return q.Apply(cursorApplier.apply) return q.Apply(cursorApplier.apply)
} }
func (a listVillagesParamsApplier) sortToColumnAndDirection(
s domain.VillageSort,
) (bun.Safe, sortDirection, error) {
switch s {
case domain.VillageSortIDASC:
return "village.id", sortDirectionASC, nil
case domain.VillageSortIDDESC:
return "village.id", sortDirectionDESC, nil
case domain.VillageSortServerKeyASC:
return "village.server_key", sortDirectionASC, nil
case domain.VillageSortServerKeyDESC:
return "village.server_key", sortDirectionDESC, nil
default:
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
}
}