126 lines
2.1 KiB
Go
126 lines
2.1 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type Service struct {
|
|
repo *Repository
|
|
|
|
// Small in-memory cache to avoid hitting the DB on every request.
|
|
// Updated on SetString; lazy-filled on first Get.
|
|
mu sync.RWMutex
|
|
cache map[string]string
|
|
}
|
|
|
|
func NewService(r *Repository) *Service {
|
|
return &Service{repo: r, cache: make(map[string]string)}
|
|
}
|
|
|
|
func (s *Service) List() ([]ConfigEntry, error) {
|
|
entries, err := s.repo.List()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// refresh cache snapshot
|
|
s.mu.Lock()
|
|
for _, e := range entries {
|
|
s.cache[e.Key] = e.Value
|
|
}
|
|
s.mu.Unlock()
|
|
return entries, nil
|
|
}
|
|
|
|
func (s *Service) SetString(key, value string) error {
|
|
if err := s.repo.Upsert(key, value); err != nil {
|
|
return err
|
|
}
|
|
s.mu.Lock()
|
|
s.cache[key] = value
|
|
s.mu.Unlock()
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) GetStringDefault(key, def string) string {
|
|
s.mu.RLock()
|
|
v, ok := s.cache[key]
|
|
s.mu.RUnlock()
|
|
if ok {
|
|
if v == "" {
|
|
return def
|
|
}
|
|
return v
|
|
}
|
|
|
|
e, err := s.repo.Get(key)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
|
|
s.mu.Lock()
|
|
s.cache[key] = e.Value
|
|
s.mu.Unlock()
|
|
|
|
if e.Value == "" {
|
|
return def
|
|
}
|
|
return e.Value
|
|
}
|
|
|
|
func (s *Service) GetIntDefault(key string, def int) int {
|
|
v := s.GetStringDefault(key, "")
|
|
if v == "" {
|
|
return def
|
|
}
|
|
n, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
return n
|
|
}
|
|
|
|
func (s *Service) GetInt64Default(key string, def int64) int64 {
|
|
v := s.GetStringDefault(key, "")
|
|
if v == "" {
|
|
return def
|
|
}
|
|
n, err := strconv.ParseInt(v, 10, 64)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
return n
|
|
}
|
|
|
|
func (s *Service) GetBoolDefault(key string, def bool) bool {
|
|
v := s.GetStringDefault(key, "")
|
|
if v == "" {
|
|
return def
|
|
}
|
|
b, err := strconv.ParseBool(v)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
return b
|
|
}
|
|
|
|
func (s *Service) GetDurationSecondsDefault(key string, def time.Duration) time.Duration {
|
|
v := s.GetStringDefault(key, "")
|
|
if v == "" {
|
|
return def
|
|
}
|
|
n, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
return time.Duration(n) * time.Second
|
|
}
|
|
|
|
func IsNotFound(err error) bool {
|
|
return errors.Is(err, gorm.ErrRecordNotFound)
|
|
}
|