core/internal/domain/ennoblement.go

299 lines
6.2 KiB
Go

package domain
import (
"fmt"
"math"
"slices"
"time"
)
type Ennoblement struct {
id int
serverKey string
villageID int
newOwnerID int
newTribeID int
oldOwnerID int
oldTribeID int
points int
createdAt time.Time
}
const ennoblementModelName = "Ennoblement"
// UnmarshalEnnoblementFromDatabase unmarshals Ennoblement from the database.
//
// It should be used only for unmarshalling from the database!
// You can't use UnmarshalEnnoblementFromDatabase as constructor - It may put domain into the invalid state!
func UnmarshalEnnoblementFromDatabase(
id int,
serverKey string,
villageID int,
newOwnerID int,
newTribeID int,
oldOwnerID int,
oldTribeID int,
points int,
createdAt time.Time,
) (Ennoblement, error) {
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
return Ennoblement{}, ValidationError{
Model: ennoblementModelName,
Field: "id",
Err: err,
}
}
if err := validateServerKey(serverKey); err != nil {
return Ennoblement{}, ValidationError{
Model: ennoblementModelName,
Field: "serverKey",
Err: err,
}
}
return Ennoblement{
id: id,
serverKey: serverKey,
villageID: villageID,
newOwnerID: newOwnerID,
newTribeID: newTribeID,
oldOwnerID: oldOwnerID,
oldTribeID: oldTribeID,
points: points,
createdAt: createdAt,
}, nil
}
func (e Ennoblement) ID() int {
return e.id
}
func (e Ennoblement) ServerKey() string {
return e.serverKey
}
func (e Ennoblement) VillageID() int {
return e.villageID
}
func (e Ennoblement) NewOwnerID() int {
return e.newOwnerID
}
func (e Ennoblement) NewTribeID() int {
return e.newTribeID
}
func (e Ennoblement) OldOwnerID() int {
return e.oldOwnerID
}
func (e Ennoblement) OldTribeID() int {
return e.oldTribeID
}
func (e Ennoblement) Points() int {
return e.points
}
func (e Ennoblement) CreatedAt() time.Time {
return e.createdAt
}
func (e Ennoblement) Base() BaseEnnoblement {
return BaseEnnoblement{
villageID: e.villageID,
newOwnerID: e.newOwnerID,
newTribeID: e.newTribeID,
oldOwnerID: e.oldOwnerID,
oldTribeID: e.oldTribeID,
points: e.points,
createdAt: e.createdAt,
}
}
type Ennoblements []Ennoblement
type CreateEnnoblementParams struct {
base BaseEnnoblement
serverKey string
}
const createEnnoblementParamsModelName = "CreateEnnoblementParams"
func NewCreateEnnoblementParams(serverKey string, ennoblements BaseEnnoblements) ([]CreateEnnoblementParams, error) {
if err := validateServerKey(serverKey); err != nil {
return nil, ValidationError{
Model: createEnnoblementParamsModelName,
Field: "serverKey",
Err: err,
}
}
params := make([]CreateEnnoblementParams, 0, len(ennoblements))
for i, e := range ennoblements {
if e.IsZero() {
return nil, fmt.Errorf("ennoblements[%d] is an empty struct", i)
}
params = append(params, CreateEnnoblementParams{
base: e,
serverKey: serverKey,
})
}
return params, nil
}
func (params CreateEnnoblementParams) Base() BaseEnnoblement {
return params.base
}
func (params CreateEnnoblementParams) ServerKey() string {
return params.serverKey
}
type EnnoblementSort uint8
const (
EnnoblementSortCreatedAtASC EnnoblementSort = iota + 1
EnnoblementSortCreatedAtDESC
EnnoblementSortIDASC
EnnoblementSortIDDESC
EnnoblementSortServerKeyASC
EnnoblementSortServerKeyDESC
)
// IsInConflict returns true if two sorts can't be used together (e.g. EnnoblementSortIDASC and EnnoblementSortIDDESC).
func (s EnnoblementSort) IsInConflict(s2 EnnoblementSort) bool {
ss := []EnnoblementSort{s, s2}
slices.Sort(ss)
// ASC is always an odd number, DESC is always an even number
return (ss[0]%2 == 1 && ss[0] == ss[1]-1) || ss[0] == ss[1]
}
//nolint:gocyclo
func (s EnnoblementSort) String() string {
switch s {
case EnnoblementSortCreatedAtASC:
return "createdAt:ASC"
case EnnoblementSortCreatedAtDESC:
return "createdAt:DESC"
case EnnoblementSortIDASC:
return "id:ASC"
case EnnoblementSortIDDESC:
return "id:DESC"
case EnnoblementSortServerKeyASC:
return "serverKey:ASC"
case EnnoblementSortServerKeyDESC:
return "serverKey:DESC"
default:
return "unknown ennoblement sort"
}
}
type ListEnnoblementsParams struct {
serverKeys []string
sort []EnnoblementSort
limit int
offset int
}
const (
EnnoblementListMaxLimit = 200
listEnnoblementsParamsModelName = "ListEnnoblementsParams"
)
func NewListEnnoblementsParams() ListEnnoblementsParams {
return ListEnnoblementsParams{
sort: []EnnoblementSort{
EnnoblementSortServerKeyASC,
EnnoblementSortCreatedAtASC,
EnnoblementSortIDASC,
},
limit: EnnoblementListMaxLimit,
}
}
func (params *ListEnnoblementsParams) ServerKeys() []string {
return params.serverKeys
}
func (params *ListEnnoblementsParams) SetServerKeys(serverKeys []string) error {
for i, sk := range serverKeys {
if err := validateServerKey(sk); err != nil {
return SliceElementValidationError{
Model: listEnnoblementsParamsModelName,
Field: "serverKeys",
Index: i,
Err: err,
}
}
}
params.serverKeys = serverKeys
return nil
}
func (params *ListEnnoblementsParams) Sort() []EnnoblementSort {
return params.sort
}
const (
ennoblementSortMinLength = 1
ennoblementSortMaxLength = 3
)
func (params *ListEnnoblementsParams) SetSort(sort []EnnoblementSort) error {
if err := validateSort(sort, ennoblementSortMinLength, ennoblementSortMaxLength); err != nil {
return ValidationError{
Model: listEnnoblementsParamsModelName,
Field: "sort",
Err: err,
}
}
params.sort = sort
return nil
}
func (params *ListEnnoblementsParams) Limit() int {
return params.limit
}
func (params *ListEnnoblementsParams) SetLimit(limit int) error {
if err := validateIntInRange(limit, 1, EnnoblementListMaxLimit); err != nil {
return ValidationError{
Model: listEnnoblementsParamsModelName,
Field: "limit",
Err: err,
}
}
params.limit = limit
return nil
}
func (params *ListEnnoblementsParams) Offset() int {
return params.offset
}
func (params *ListEnnoblementsParams) SetOffset(offset int) error {
if err := validateIntInRange(offset, 0, math.MaxInt); err != nil {
return ValidationError{
Model: listEnnoblementsParamsModelName,
Field: "offset",
Err: err,
}
}
params.offset = offset
return nil
}