Hermes/internal/core/services/shortlink_service.go

86 lines
1.8 KiB
Go

package services
import (
"backend/internal/core/repos"
"backend/pkg/cache"
"backend/pkg/charsets"
"context"
"fmt"
"math/rand"
"time"
)
var (
ErrShortlinkNotexist = fmt.Errorf("shortlink does not exist or expired")
ErrShortlinkExpired = fmt.Errorf("shortlink expired")
)
type ShortlinkService interface {
CreateShortlink(ctx context.Context, url string) (string, error)
GetShortlink(ctx context.Context, id string) (string, error)
ShortlinkRoutine(ctx context.Context) error
}
type NewShortlinkServiceParams struct {
Cache cache.Cache[string, string]
Repo repos.ShortlinkRepo
}
func NewShortlinkSevice(params NewShortlinkServiceParams) ShortlinkService {
return &shortlinkService{
cache: params.Cache,
repo: params.Repo,
}
}
type shortlinkService struct {
cache cache.Cache[string, string]
repo repos.ShortlinkRepo
}
func (s *shortlinkService) CreateShortlink(ctx context.Context, url string) (string, error) {
charset := charsets.GetCharset(charsets.CharsetTypeAll)
src := rand.NewSource(time.Now().UnixMicro())
randGen := rand.New(src)
id := charset.RandomString(randGen, 10)
expiration := time.Now().Add(7 * 24 * time.Hour)
dto := repos.ShortlinkDTO{
Id: id,
Url: url,
ExpiresAt: expiration,
}
if err := s.repo.AddShortlink(ctx, dto); err != nil {
return "", err
}
s.cache.Set(id, url, cache.Expiration{ExpiresAt: expiration})
return id, nil
}
func (s *shortlinkService) GetShortlink(ctx context.Context, id string) (string, error) {
if link, ok := s.cache.Get(id); ok {
return link, nil
}
link, err := s.repo.GetShortlink(ctx, id)
if err != nil {
return "", err
}
if link == nil {
return "", ErrShortlinkNotexist
}
if time.Now().After(link.ExpiresAt) {
return "", ErrShortlinkExpired
}
return link.Url, nil
}
func (s *shortlinkService) ShortlinkRoutine(ctx context.Context) error {
return nil
}