This repository has been archived on 2022-09-04. You can view files and clone it, but cannot push or open issues or pull requests.
api/ennoblement/repository/pg_repository.go
2020-06-12 18:26:48 +02:00

97 lines
2.5 KiB
Go

package repository
import (
"context"
"encoding/json"
"fmt"
"time"
"github.com/go-redis/redis/v8"
"github.com/tribalwarshelp/api/ennoblement"
"github.com/go-pg/pg/v10"
"github.com/pkg/errors"
"github.com/tribalwarshelp/shared/models"
)
var (
cacheKey = "ennoblements-%s"
expiration = time.Second * 15
)
type pgRepository struct {
*pg.DB
cache redis.UniversalClient
}
func NewPGRepository(db *pg.DB, cache redis.UniversalClient) ennoblement.Repository {
return &pgRepository{db, cache}
}
func (repo *pgRepository) Fetch(ctx context.Context, server string) ([]*models.Ennoblement, error) {
if ennoblements, loaded := repo.loadEnnoblementsFromCache(server); loaded {
return ennoblements, nil
}
s := &models.Server{}
if err := repo.Model(s).Where("key = ?", server).Relation("LangVersion").Select(); err != nil {
if err == pg.ErrNoRows {
return nil, fmt.Errorf("Server not found")
}
return nil, errors.Wrap(err, "Internal server error")
}
if s.Status == models.ServerStatusClosed {
return nil, fmt.Errorf("Server is " + models.ServerStatusClosed.String())
}
url := "https://" + s.Key + "." + s.LangVersion.Host +
fmt.Sprintf(ennoblement.EndpointGetConquer, time.Now().Add(-1*time.Hour).Unix())
lines, err := getCSVData(url)
if err != nil {
return nil, errors.Wrap(err, "Cannot fetch ennoblements")
}
e := []*models.Ennoblement{}
lineParser, err := newLineParser(s.LangVersion.Timezone)
if err != nil {
return nil, err
}
for _, line := range lines {
ennoblement, err := lineParser.parse(line)
if err != nil {
continue
}
e = append(e, ennoblement)
}
go repo.cacheEnnoblements(server, e)
return e, nil
}
func (repo *pgRepository) loadEnnoblementsFromCache(server string) ([]*models.Ennoblement, bool) {
ennoblementsJSON, err := repo.cache.Get(context.Background(), fmt.Sprintf(cacheKey, server)).Result()
if err != nil || ennoblementsJSON == "" {
return nil, false
}
ennoblements := []*models.Ennoblement{}
if json.Unmarshal([]byte(ennoblementsJSON), &ennoblements) != nil {
return nil, false
}
return ennoblements, true
}
func (repo *pgRepository) cacheEnnoblements(server string, ennoblements []*models.Ennoblement) error {
ennoblementsJSON, err := json.Marshal(&ennoblements)
if err != nil {
return errors.Wrap(err, "cacheEnnoblements")
}
if err := repo.cache.Set(context.Background(), fmt.Sprintf(cacheKey, server), ennoblementsJSON, expiration).Err(); err != nil {
return errors.Wrap(err, "cacheEnnoblements")
}
return nil
}