86 lines
1.8 KiB
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
|
|
}
|