Dawid Wysokiński
9d5987f74c
All checks were successful
ci/woodpecker/push/govulncheck Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/tag/release Pipeline was successful
ci/woodpecker/tag/deployment Pipeline was successful
ci/woodpecker/cron/govulncheck Pipeline was successful
Reviewed-on: #52
659 lines
15 KiB
Go
659 lines
15 KiB
Go
package domain
|
|
|
|
import (
|
|
"errors"
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
type ServerSnapshot struct {
|
|
id int
|
|
serverKey string
|
|
numPlayers int
|
|
numActivePlayers int
|
|
numInactivePlayers int
|
|
numTribes int
|
|
numActiveTribes int
|
|
numInactiveTribes int
|
|
numVillages int
|
|
numPlayerVillages int
|
|
numBarbarianVillages int
|
|
numBonusVillages int
|
|
date time.Time
|
|
createdAt time.Time
|
|
}
|
|
|
|
const serverSnapshotModelName = "ServerSnapshot"
|
|
|
|
// UnmarshalServerSnapshotFromDatabase unmarshals ServerSnapshot from the database.
|
|
//
|
|
// It should be used only for unmarshalling from the database!
|
|
// You can't use UnmarshalServerSnapshotFromDatabase as constructor - It may put domain into the invalid state!
|
|
func UnmarshalServerSnapshotFromDatabase(
|
|
id int,
|
|
serverKey string,
|
|
numPlayers int,
|
|
numActivePlayers int,
|
|
numInactivePlayers int,
|
|
numTribes int,
|
|
numActiveTribes int,
|
|
numInactiveTribes int,
|
|
numVillages int,
|
|
numPlayerVillages int,
|
|
numBarbarianVillages int,
|
|
numBonusVillages int,
|
|
date time.Time,
|
|
createdAt time.Time,
|
|
) (ServerSnapshot, error) {
|
|
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
|
|
return ServerSnapshot{}, ValidationError{
|
|
Model: serverSnapshotModelName,
|
|
Field: "id",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
if err := validateServerKey(serverKey); err != nil {
|
|
return ServerSnapshot{}, ValidationError{
|
|
Model: serverSnapshotModelName,
|
|
Field: "serverKey",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
return ServerSnapshot{
|
|
id: id,
|
|
serverKey: serverKey,
|
|
numPlayers: numPlayers,
|
|
numActivePlayers: numActivePlayers,
|
|
numInactivePlayers: numInactivePlayers,
|
|
numTribes: numTribes,
|
|
numActiveTribes: numActiveTribes,
|
|
numInactiveTribes: numInactiveTribes,
|
|
numVillages: numVillages,
|
|
numPlayerVillages: numPlayerVillages,
|
|
numBarbarianVillages: numBarbarianVillages,
|
|
numBonusVillages: numBonusVillages,
|
|
date: date,
|
|
createdAt: createdAt,
|
|
}, nil
|
|
}
|
|
|
|
func (ss ServerSnapshot) ID() int {
|
|
return ss.id
|
|
}
|
|
|
|
func (ss ServerSnapshot) ServerKey() string {
|
|
return ss.serverKey
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumPlayers() int {
|
|
return ss.numPlayers
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumActivePlayers() int {
|
|
return ss.numActivePlayers
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumInactivePlayers() int {
|
|
return ss.numInactivePlayers
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumTribes() int {
|
|
return ss.numTribes
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumActiveTribes() int {
|
|
return ss.numActiveTribes
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumInactiveTribes() int {
|
|
return ss.numInactiveTribes
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumVillages() int {
|
|
return ss.numVillages
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumPlayerVillages() int {
|
|
return ss.numPlayerVillages
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumBarbarianVillages() int {
|
|
return ss.numBarbarianVillages
|
|
}
|
|
|
|
func (ss ServerSnapshot) NumBonusVillages() int {
|
|
return ss.numBonusVillages
|
|
}
|
|
|
|
func (ss ServerSnapshot) Date() time.Time {
|
|
return ss.date
|
|
}
|
|
|
|
func (ss ServerSnapshot) CreatedAt() time.Time {
|
|
return ss.createdAt
|
|
}
|
|
|
|
func (ss ServerSnapshot) WithRelations(server ServerMeta) ServerSnapshotWithRelations {
|
|
return ServerSnapshotWithRelations{
|
|
snapshot: ss,
|
|
server: server,
|
|
}
|
|
}
|
|
|
|
func (ss ServerSnapshot) ToCursor() (ServerSnapshotCursor, error) {
|
|
return NewServerSnapshotCursor(ss.id, ss.serverKey, ss.date)
|
|
}
|
|
|
|
func (ss ServerSnapshot) IsZero() bool {
|
|
return ss == ServerSnapshot{}
|
|
}
|
|
|
|
type ServerSnapshots []ServerSnapshot
|
|
|
|
type ServerSnapshotWithRelations struct {
|
|
snapshot ServerSnapshot
|
|
server ServerMeta
|
|
}
|
|
|
|
func (ts ServerSnapshotWithRelations) ServerSnapshot() ServerSnapshot {
|
|
return ts.snapshot
|
|
}
|
|
|
|
func (ts ServerSnapshotWithRelations) Server() ServerMeta {
|
|
return ts.server
|
|
}
|
|
|
|
func (ts ServerSnapshotWithRelations) IsZero() bool {
|
|
return ts.snapshot.IsZero()
|
|
}
|
|
|
|
type ServerSnapshotsWithRelations []ServerSnapshotWithRelations
|
|
|
|
type CreateServerSnapshotParams struct {
|
|
serverKey string
|
|
numPlayers int
|
|
numActivePlayers int
|
|
numInactivePlayers int
|
|
numTribes int
|
|
numActiveTribes int
|
|
numInactiveTribes int
|
|
numVillages int
|
|
numPlayerVillages int
|
|
numBarbarianVillages int
|
|
numBonusVillages int
|
|
date time.Time
|
|
}
|
|
|
|
func NewCreateServerSnapshotParams(server Server, date time.Time) (CreateServerSnapshotParams, error) {
|
|
if server.IsZero() {
|
|
return CreateServerSnapshotParams{}, errors.New("given server is an empty struct")
|
|
}
|
|
|
|
if !server.Open() {
|
|
return CreateServerSnapshotParams{}, errors.New("given server is closed")
|
|
}
|
|
|
|
return CreateServerSnapshotParams{
|
|
serverKey: server.Key(),
|
|
numPlayers: server.NumPlayers(),
|
|
numActivePlayers: server.NumActivePlayers(),
|
|
numInactivePlayers: server.NumInactivePlayers(),
|
|
numTribes: server.NumTribes(),
|
|
numActiveTribes: server.NumActiveTribes(),
|
|
numInactiveTribes: server.NumInactiveTribes(),
|
|
numVillages: server.NumVillages(),
|
|
numPlayerVillages: server.NumPlayerVillages(),
|
|
numBarbarianVillages: server.NumBarbarianVillages(),
|
|
numBonusVillages: server.NumBonusVillages(),
|
|
date: date,
|
|
}, nil
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) ServerKey() string {
|
|
return params.serverKey
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumPlayers() int {
|
|
return params.numPlayers
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumActivePlayers() int {
|
|
return params.numActivePlayers
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumInactivePlayers() int {
|
|
return params.numInactivePlayers
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumTribes() int {
|
|
return params.numTribes
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumActiveTribes() int {
|
|
return params.numActiveTribes
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumInactiveTribes() int {
|
|
return params.numInactiveTribes
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumVillages() int {
|
|
return params.numVillages
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumPlayerVillages() int {
|
|
return params.numPlayerVillages
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumBarbarianVillages() int {
|
|
return params.numBarbarianVillages
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) NumBonusVillages() int {
|
|
return params.numBonusVillages
|
|
}
|
|
|
|
func (params CreateServerSnapshotParams) Date() time.Time {
|
|
return params.date
|
|
}
|
|
|
|
type ServerSnapshotSort uint8
|
|
|
|
const (
|
|
ServerSnapshotSortDateASC ServerSnapshotSort = iota + 1
|
|
ServerSnapshotSortDateDESC
|
|
ServerSnapshotSortIDASC
|
|
ServerSnapshotSortIDDESC
|
|
ServerSnapshotSortServerKeyASC
|
|
ServerSnapshotSortServerKeyDESC
|
|
)
|
|
|
|
// IsInConflict returns true if two sorts can't be used together
|
|
// (e.g. ServerSnapshotSortIDASC and ServerSnapshotSortIDDESC).
|
|
func (s ServerSnapshotSort) IsInConflict(s2 ServerSnapshotSort) bool {
|
|
return isSortInConflict(s, s2)
|
|
}
|
|
|
|
//nolint:gocyclo
|
|
func (s ServerSnapshotSort) String() string {
|
|
switch s {
|
|
case ServerSnapshotSortDateASC:
|
|
return "date:ASC"
|
|
case ServerSnapshotSortDateDESC:
|
|
return "date:DESC"
|
|
case ServerSnapshotSortIDASC:
|
|
return "id:ASC"
|
|
case ServerSnapshotSortIDDESC:
|
|
return "id:DESC"
|
|
case ServerSnapshotSortServerKeyASC:
|
|
return "serverKey:ASC"
|
|
case ServerSnapshotSortServerKeyDESC:
|
|
return "serverKey:DESC"
|
|
default:
|
|
return "unknown server snapshot sort"
|
|
}
|
|
}
|
|
|
|
type ServerSnapshotCursor struct {
|
|
id int
|
|
serverKey string
|
|
date time.Time
|
|
}
|
|
|
|
const serverSnapshotCursorModelName = "ServerSnapshotCursor"
|
|
|
|
func NewServerSnapshotCursor(id int, serverKey string, date time.Time) (ServerSnapshotCursor, error) {
|
|
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
|
|
return ServerSnapshotCursor{}, ValidationError{
|
|
Model: serverSnapshotCursorModelName,
|
|
Field: "id",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
if err := validateServerKey(serverKey); err != nil {
|
|
return ServerSnapshotCursor{}, ValidationError{
|
|
Model: serverSnapshotCursorModelName,
|
|
Field: "serverKey",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
return ServerSnapshotCursor{
|
|
id: id,
|
|
serverKey: serverKey,
|
|
date: date,
|
|
}, nil
|
|
}
|
|
|
|
func decodeServerSnapshotCursor(encoded string) (ServerSnapshotCursor, error) {
|
|
m, err := decodeCursor(encoded)
|
|
if err != nil {
|
|
return ServerSnapshotCursor{}, err
|
|
}
|
|
|
|
id, err := m.int("id")
|
|
if err != nil {
|
|
return ServerSnapshotCursor{}, ErrInvalidCursor
|
|
}
|
|
|
|
serverKey, err := m.string("serverKey")
|
|
if err != nil {
|
|
return ServerSnapshotCursor{}, ErrInvalidCursor
|
|
}
|
|
|
|
date, err := m.time("date")
|
|
if err != nil {
|
|
return ServerSnapshotCursor{}, ErrInvalidCursor
|
|
}
|
|
|
|
tsc, err := NewServerSnapshotCursor(
|
|
id,
|
|
serverKey,
|
|
date,
|
|
)
|
|
if err != nil {
|
|
return ServerSnapshotCursor{}, ErrInvalidCursor
|
|
}
|
|
|
|
return tsc, nil
|
|
}
|
|
|
|
func (ssc ServerSnapshotCursor) ID() int {
|
|
return ssc.id
|
|
}
|
|
|
|
func (ssc ServerSnapshotCursor) ServerKey() string {
|
|
return ssc.serverKey
|
|
}
|
|
|
|
func (ssc ServerSnapshotCursor) Date() time.Time {
|
|
return ssc.date
|
|
}
|
|
|
|
func (ssc ServerSnapshotCursor) IsZero() bool {
|
|
return ssc == ServerSnapshotCursor{}
|
|
}
|
|
|
|
func (ssc ServerSnapshotCursor) Encode() string {
|
|
if ssc.IsZero() {
|
|
return ""
|
|
}
|
|
|
|
return encodeCursor([]keyValuePair{
|
|
{"id", ssc.id},
|
|
{"serverKey", ssc.serverKey},
|
|
{"date", ssc.date},
|
|
})
|
|
}
|
|
|
|
type ListServerSnapshotsParams struct {
|
|
serverKeys []string
|
|
sort []ServerSnapshotSort
|
|
cursor ServerSnapshotCursor
|
|
limit int
|
|
}
|
|
|
|
const (
|
|
ServerSnapshotListMaxLimit = 500
|
|
listServerSnapshotsParamsModelName = "ListServerSnapshotsParams"
|
|
)
|
|
|
|
func NewListServerSnapshotsParams() ListServerSnapshotsParams {
|
|
return ListServerSnapshotsParams{
|
|
sort: []ServerSnapshotSort{
|
|
ServerSnapshotSortServerKeyASC,
|
|
ServerSnapshotSortDateASC,
|
|
ServerSnapshotSortIDASC,
|
|
},
|
|
limit: ServerSnapshotListMaxLimit,
|
|
}
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) ServerKeys() []string {
|
|
return params.serverKeys
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) SetServerKeys(serverKeys []string) error {
|
|
for i, sk := range serverKeys {
|
|
if err := validateServerKey(sk); err != nil {
|
|
return SliceElementValidationError{
|
|
Model: listServerSnapshotsParamsModelName,
|
|
Field: "serverKeys",
|
|
Index: i,
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
params.serverKeys = serverKeys
|
|
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) Sort() []ServerSnapshotSort {
|
|
return params.sort
|
|
}
|
|
|
|
const (
|
|
serverSnapshotSortMinLength = 0
|
|
serverSnapshotSortMaxLength = 3
|
|
)
|
|
|
|
func (params *ListServerSnapshotsParams) SetSort(sort []ServerSnapshotSort) error {
|
|
if err := validateSort(sort, serverSnapshotSortMinLength, serverSnapshotSortMaxLength); err != nil {
|
|
return ValidationError{
|
|
Model: listServerSnapshotsParamsModelName,
|
|
Field: "sort",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
params.sort = sort
|
|
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) PrependSort(sort []ServerSnapshotSort) error {
|
|
if len(sort) == 0 {
|
|
return nil
|
|
}
|
|
|
|
if err := validateSliceLen(sort, 0, max(serverSnapshotSortMaxLength-len(params.sort), 0)); err != nil {
|
|
return ValidationError{
|
|
Model: listServerSnapshotsParamsModelName,
|
|
Field: "sort",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
return params.SetSort(append(sort, params.sort...))
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) PrependSortString(
|
|
sort []string,
|
|
allowed []ServerSnapshotSort,
|
|
maxLength int,
|
|
) error {
|
|
if len(sort) == 0 {
|
|
return nil
|
|
}
|
|
|
|
if err := validateSliceLen(sort, 0, max(min(serverSnapshotSortMaxLength-len(params.sort), maxLength), 0)); err != nil {
|
|
return ValidationError{
|
|
Model: listServerSnapshotsParamsModelName,
|
|
Field: "sort",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
toPrepend := make([]ServerSnapshotSort, 0, len(sort))
|
|
|
|
for i, s := range sort {
|
|
converted, err := newSortFromString(s, allowed...)
|
|
if err != nil {
|
|
return SliceElementValidationError{
|
|
Model: listServerSnapshotsParamsModelName,
|
|
Field: "sort",
|
|
Index: i,
|
|
Err: err,
|
|
}
|
|
}
|
|
toPrepend = append(toPrepend, converted)
|
|
}
|
|
|
|
return params.SetSort(append(toPrepend, params.sort...))
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) Cursor() ServerSnapshotCursor {
|
|
return params.cursor
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) SetCursor(cursor ServerSnapshotCursor) error {
|
|
params.cursor = cursor
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) SetEncodedCursor(encoded string) error {
|
|
decoded, err := decodeServerSnapshotCursor(encoded)
|
|
if err != nil {
|
|
return ValidationError{
|
|
Model: listServerSnapshotsParamsModelName,
|
|
Field: "cursor",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
params.cursor = decoded
|
|
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) Limit() int {
|
|
return params.limit
|
|
}
|
|
|
|
func (params *ListServerSnapshotsParams) SetLimit(limit int) error {
|
|
if err := validateIntInRange(limit, 1, ServerSnapshotListMaxLimit); err != nil {
|
|
return ValidationError{
|
|
Model: listServerSnapshotsParamsModelName,
|
|
Field: "limit",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
params.limit = limit
|
|
|
|
return nil
|
|
}
|
|
|
|
type ListServerSnapshotsResult struct {
|
|
snapshots ServerSnapshots
|
|
self ServerSnapshotCursor
|
|
next ServerSnapshotCursor
|
|
}
|
|
|
|
const listServerSnapshotsResultModelName = "ListServerSnapshotsResult"
|
|
|
|
func NewListServerSnapshotsResult(
|
|
snapshots ServerSnapshots,
|
|
next ServerSnapshot,
|
|
) (ListServerSnapshotsResult, error) {
|
|
var err error
|
|
res := ListServerSnapshotsResult{
|
|
snapshots: snapshots,
|
|
}
|
|
|
|
if len(snapshots) > 0 {
|
|
res.self, err = snapshots[0].ToCursor()
|
|
if err != nil {
|
|
return ListServerSnapshotsResult{}, ValidationError{
|
|
Model: listServerSnapshotsResultModelName,
|
|
Field: "self",
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
if !next.IsZero() {
|
|
res.next, err = next.ToCursor()
|
|
if err != nil {
|
|
return ListServerSnapshotsResult{}, ValidationError{
|
|
Model: listServerSnapshotsResultModelName,
|
|
Field: "next",
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (res ListServerSnapshotsResult) ServerSnapshots() ServerSnapshots {
|
|
return res.snapshots
|
|
}
|
|
|
|
func (res ListServerSnapshotsResult) Self() ServerSnapshotCursor {
|
|
return res.self
|
|
}
|
|
|
|
func (res ListServerSnapshotsResult) Next() ServerSnapshotCursor {
|
|
return res.next
|
|
}
|
|
|
|
type ListServerSnapshotsWithRelationsResult struct {
|
|
snapshots ServerSnapshotsWithRelations
|
|
self ServerSnapshotCursor
|
|
next ServerSnapshotCursor
|
|
}
|
|
|
|
const listServerSnapshotsWithRelationsResultModelName = "ListServerSnapshotsWithRelationsResult"
|
|
|
|
func NewListServerSnapshotsWithRelationsResult(
|
|
snapshots ServerSnapshotsWithRelations,
|
|
next ServerSnapshotWithRelations,
|
|
) (ListServerSnapshotsWithRelationsResult, error) {
|
|
var err error
|
|
res := ListServerSnapshotsWithRelationsResult{
|
|
snapshots: snapshots,
|
|
}
|
|
|
|
if len(snapshots) > 0 {
|
|
res.self, err = snapshots[0].ServerSnapshot().ToCursor()
|
|
if err != nil {
|
|
return ListServerSnapshotsWithRelationsResult{}, ValidationError{
|
|
Model: listServerSnapshotsWithRelationsResultModelName,
|
|
Field: "self",
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
if !next.IsZero() {
|
|
res.next, err = next.ServerSnapshot().ToCursor()
|
|
if err != nil {
|
|
return ListServerSnapshotsWithRelationsResult{}, ValidationError{
|
|
Model: listServerSnapshotsWithRelationsResultModelName,
|
|
Field: "next",
|
|
Err: err,
|
|
}
|
|
}
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (res ListServerSnapshotsWithRelationsResult) ServerSnapshots() ServerSnapshotsWithRelations {
|
|
return res.snapshots
|
|
}
|
|
|
|
func (res ListServerSnapshotsWithRelationsResult) Self() ServerSnapshotCursor {
|
|
return res.self
|
|
}
|
|
|
|
func (res ListServerSnapshotsWithRelationsResult) Next() ServerSnapshotCursor {
|
|
return res.next
|
|
}
|