128 lines
3.2 KiB
Go
128 lines
3.2 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
|
)
|
|
|
|
type ServerRepository interface {
|
|
CreateOrUpdate(ctx context.Context, params ...domain.CreateServerParams) error
|
|
List(ctx context.Context, params domain.ListServersParams) (domain.Servers, error)
|
|
}
|
|
|
|
type ServerService struct {
|
|
repo ServerRepository
|
|
twSvc TWService
|
|
}
|
|
|
|
func NewServerService(repo ServerRepository, twSvc TWService) *ServerService {
|
|
return &ServerService{repo: repo, twSvc: twSvc}
|
|
}
|
|
|
|
func (svc *ServerService) Sync(ctx context.Context, payload domain.SyncServersCmdPayload) error {
|
|
versionCode := payload.VersionCode()
|
|
|
|
openServers, err := svc.twSvc.GetOpenServers(ctx, payload.URL().String())
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't get open servers for version code %s: %w", versionCode, err)
|
|
}
|
|
|
|
specialServers, err := svc.listAllSpecial(ctx, versionCode)
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't list special servers with version code %s: %w", versionCode, err)
|
|
}
|
|
|
|
currentlyStoredOpenServers, err := svc.listAllOpen(ctx, versionCode)
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't list open servers with version code %s: %w", versionCode, err)
|
|
}
|
|
|
|
openServersWithoutSpecial := openServers.FilterOutSpecial(specialServers)
|
|
|
|
serversToBeClosed, err := currentlyStoredOpenServers.Close(openServersWithoutSpecial)
|
|
if err != nil {
|
|
return fmt.Errorf("couldn't close servers: %w", err)
|
|
}
|
|
|
|
params, err := domain.NewCreateServerParams(append(openServersWithoutSpecial, serversToBeClosed...), versionCode)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return svc.repo.CreateOrUpdate(ctx, params...)
|
|
}
|
|
|
|
func (svc *ServerService) listAllSpecial(ctx context.Context, versionCode string) (domain.Servers, error) {
|
|
params := domain.NewListServersParams()
|
|
|
|
if err := params.SetVersionCodes([]string{versionCode}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := params.SetSpecial(domain.NullBool{
|
|
Value: true,
|
|
Valid: true,
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return svc.ListAll(ctx, params)
|
|
}
|
|
|
|
func (svc *ServerService) listAllOpen(ctx context.Context, versionCode string) (domain.Servers, error) {
|
|
params := domain.NewListServersParams()
|
|
|
|
if err := params.SetVersionCodes([]string{versionCode}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := params.SetOpen(domain.NullBool{
|
|
Value: true,
|
|
Valid: true,
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return svc.ListAll(ctx, params)
|
|
}
|
|
|
|
// ListAll retrieves all servers from the database based on the given params in an optimal way.
|
|
// You can't specify a custom limit/offset/sort/keyGT for this operation.
|
|
func (svc *ServerService) ListAll(ctx context.Context, params domain.ListServersParams) (domain.Servers, error) {
|
|
if err := params.SetOffset(0); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := params.SetLimit(domain.ServerListMaxLimit); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := params.SetSort([]domain.ServerSort{domain.ServerSortKeyASC}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var servers domain.Servers
|
|
|
|
for {
|
|
ss, err := svc.repo.List(ctx, params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(ss) == 0 {
|
|
return servers, nil
|
|
}
|
|
|
|
servers = append(servers, ss...)
|
|
|
|
if err = params.SetKeyGT(domain.NullString{
|
|
Value: ss[len(ss)-1].Key(),
|
|
Valid: true,
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
}
|