Files
yt-dlp-webui/server/subscription/repository/repository.go

145 lines
2.9 KiB
Go

package repository
import (
"context"
"encoding/json"
"fmt"
"github.com/google/uuid"
"github.com/marcopiovanello/yt-dlp-web-ui/v3/server/subscription/data"
"github.com/marcopiovanello/yt-dlp-web-ui/v3/server/subscription/domain"
bolt "go.etcd.io/bbolt"
)
var bucketName = []byte("subscriptions")
type Repository struct {
db *bolt.DB
}
// Delete implements domain.Repository.
func (r *Repository) Delete(ctx context.Context, id string) error {
return r.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket(bucketName)
return b.Delete([]byte(id))
})
}
// GetCursor implements domain.Repository.
func (s *Repository) GetCursor(ctx context.Context, id string) (int64, error) {
var cursor int64
err := s.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("subscriptions"))
v := b.Get([]byte(id))
if v == nil {
return fmt.Errorf("subscription %s not found", id)
}
var data struct {
Cursor int64 `json:"cursor"`
}
if err := json.Unmarshal(v, &data); err != nil {
return err
}
cursor = data.Cursor
return nil
})
if err != nil {
return -1, err
}
return cursor, nil
}
// List implements domain.Repository.
func (r *Repository) List(ctx context.Context, start int64, limit int) (*[]data.Subscription, error) {
var subs []data.Subscription
err := r.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket(bucketName)
return b.ForEach(func(k, v []byte) error {
var sub data.Subscription
if err := json.Unmarshal(v, &sub); err != nil {
return err
}
subs = append(subs, sub)
return nil
})
})
if err != nil {
return nil, err
}
return &subs, nil
}
// Submit implements domain.Repository.
func (s *Repository) Submit(ctx context.Context, sub *data.Subscription) (*data.Subscription, error) {
if sub.Id == "" {
sub.Id = uuid.NewString()
}
data, err := json.Marshal(sub)
if err != nil {
return nil, err
}
err = s.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("subscriptions"))
return b.Put([]byte(sub.Id), data)
})
if err != nil {
return nil, err
}
return sub, nil
}
// UpdateByExample implements domain.Repository.
func (s *Repository) UpdateByExample(ctx context.Context, example *data.Subscription) error {
return s.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("subscriptions"))
return b.ForEach(func(k, v []byte) error {
var sub data.Subscription
if err := json.Unmarshal(v, &sub); err != nil {
return err
}
if sub.Id == example.Id || sub.URL == example.URL {
// aggiorna i campi
sub.URL = example.URL
sub.Params = example.Params
sub.CronExpr = example.CronExpr
data, err := json.Marshal(sub)
if err != nil {
return err
}
if err := b.Put(k, data); err != nil {
return err
}
}
return nil
})
})
}
func New(db *bolt.DB) domain.Repository {
db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucketIfNotExists(bucketName)
return err
})
return &Repository{
db: db,
}
}